将数据从db拉入列表时,实体框架会出现混淆行为

时间:2016-10-14 13:38:09

标签: entity-framework linq

如果我尝试将机器中的零件从数据库中的零件列表中删除,我执行此操作:

Machine ma = new Machine();
ma = dbcontext.Machine.Where(s => s.Guid == guid).ToList()[0];

IQueryable<Part> PartsQuery = from m in db.Machines
                                    where m.Guid == guid
                                    from p in m.Parts
                                    select p;

ma.parts.AddRange(PartsQuery.ToList());

我将机器的零件列表加倍,而不是数据库中的零件!

如果我这样做而不是最后一行:

List<parts> partsFromDb = PartsQuery.ToList();
ma.parts.AddRange(partsFromDb);

ma.parts列表中的部件数量是正确的。有人可以向我解释一下吗?

2 个答案:

答案 0 :(得分:1)

您可以在往返数据库的过程中实现您想要做的事情:

Machine mab=context.Machine.Include(m=>m.Parts).FirstOrDefault(m=> m.Guid == guid); 

关于您的问题,这可能是由于EF的缓存策略,也可能涉及延迟加载。我不知道你是如何测试你的代码的,但如果你做了以下的事情:

  Machine ma = context.Machine.FirstOrDefault(m=> m.Guid == guid); 

  IQueryable<Part> PartsQuery = from m in db.Machines
                                where m.Guid == guid
                                from p in m.Parts
                                select p;

 PartsQuery.ToList(); //materialize your query but don't save the result;
 var parts=ma.parts;// now take a look here and you will see the related parts were loaded

这应该是数据重复的原因,因为当您实现查询并稍后查询导航属性(m.parts)时,相关实体已经存在。但无论如何,获得所需内容的最佳方式是使用我在答案开头显示的查询。

答案 1 :(得分:0)

Machine ma = new Machine();
ma = dbcontext.Machine.Where(s => s.Guid == guid).ToList()[0];

IQueryable<Part> PartsQuery = from m in db.Machines
                                    where m.Guid == guid
                                    from p in m.Parts
                                    select p;

ma.parts.AddRange(PartsQuery.ToList());

100%相当于:

// 1. Find and retrieve the first machine with the given GUID
Machine machine = dbcontext.Machine.First(s => s.Guid == guid);
// 2. Again, find and retrieve the machines with the given GUID, select the parts of each machine that matches and flatten it down to a single list.
IList<Part> machineParts = db.Machines
                                .Where(m => m.Guid == guid)
                                .SelectMany(m => m.Parts)
                                .ToList();  
// 3. Add.. all of the parts to that machine again?  
machine.parts.AddRange(machineParts);

因此,最终在检索到的机器中使用了两倍的部件是有道理的。

说实话,我不相信你所说的最后一个改变,即将'PartsQuery'捕获到一个临时变量中,会对你machine的最终结果产生任何影响。

那里必须有其他东西。