【问题标题】:Adding to a collection created in an Entity Framework projection添加到在实体框架投影中创建的集合
【发布时间】:2023-04-10 16:31:01
【问题描述】:

我想在使用 EF 检索数据的其他实例的数据库中添加一个新实体。我希望使用如下代码:

using (var db = new FundResearchContext(null))
{
    var query = from a in db.As select new 
                {
                    a = a,
                    bs = (from b in db.Bs where b.AnId == a.AnotherId select b)
                };

    var listOfAsAndRelatedBs = query.ToList();
    listOfAsAndRelatedBs[0].bs.Add(new B());
    db.SaveChanges();
}

虽然bs 集合中的对象被跟踪并保存了对它们的更改,但我无法将新项目添加到集合中,因为它的类型为IQueryable。我意识到在这样一个简单的情况下,我可以将属性放在 A 和 B 上,以表明它们是通过外键链接的,但这种方法在我的现​​实生活场景中是不可能的。那么是否有另一种语法可以使bs 本身成为一个被跟踪的对象,我可以向其中添加新的B 对象并使它们持久化?还是我必须使用 db.Bs.Add(new B()) 手动完成所有操作?

【问题讨论】:

    标签: c# linq-to-sql entity-framework-4


    【解决方案1】:

    如果你的A 类上有一个Bs 集合,你可以说:

    var query = from a in db.As select new 
                {
                    a = a,
                    bs = a.Bs
                };
    

    这有一个很好的急切加载效果,因为每个A 的所有Bs 都在此查询实现时加载并附加。您应该能够将对象添加到其中一个结果的bs 属性或a.Bs 属性。

    如果您的实体类之间没有建立这种关系,您将无法执行此操作,并且您将无法直接添加到db.Bs。当然,您可以创建一种快捷方式对象来促进这一点:

    public class DTO {public A a{get;set;} public IObjectSet<B> allBs {get;set;} }
    
    var list = (from a in db.As 
                select new DTO
                {
                    a = a,
                }).ToList();
    foreach(var a in list)
    {
        a.allBs = db.Bs;
    }
    

    这样您不必直接访问上下文即可将项目添加到Bs

    【讨论】:

    • 你是对的,我在A 上没有可以用作导航属性的Bs 集合。似乎我需要直接添加到db.Bs 并跟踪我在与匿名投影类中的bs 属性不同的列表中添加的对象。
    【解决方案2】:

    如果在匿名对象中设置bs 时调用ToList(),则bs 的类型应为List&lt;B&gt;

    using (var db = new FundResearchContext(null))
    {
        var query = from a in db.As select new 
                    {
                        // ...
                        bs = (from b in db.Bs 
                              where b.AnId == a.AnotherId 
                              select b)
                             .ToList()
                    };
        // ...
    }
    

    【讨论】:

    • LINQ to Entities 不允许在这样的查询中调用 .ToList()。
    • 恐怕我试过了。虽然编译器对此感到满意,但当它执行时,我得到一个 System.NotSupportedException 消息“LINQ to Entities 无法识别该方法...”
    猜你喜欢
    • 2010-09-29
    • 1970-01-01
    • 1970-01-01
    • 2010-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多