如果我尝试将机器中的零件从数据库中的零件列表中删除,我执行此操作:
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列表中的部件数量是正确的。有人可以向我解释一下吗?
答案 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
的最终结果产生任何影响。
那里必须有其他东西。