如果存在已删除的相关实体,则实体框架5.Include()不会加载记录

时间:2013-04-08 09:55:05

标签: asp.net entity-framework-5 model-binding

我有一个数据库,在两个表之间有一个1..many的关系,称之为Color和Car。颜色与汽车相关联。就我而言,任何时候都可以删除颜色至关重要。没有级联删除,因此如果删除了颜色,则Car的Color_ID字段指向不存在的内容。还行吧。它们通过名为Color_ID的FK相关联。

当我这样做时会出现问题:

var query = context.Cars.Include(x => x.Colors);

这仅返回具有相关联的Color记录的Cars。我真正想要的是所有汽车,即使它们的颜色不存在,所以我可以使用GridView进行模型绑定,即 <asp:Label runat="server" Text='<%# Item.Colors == null ? "Color Deleted!" : Item.Colors %>' />

如果我删除.Include()并使用延迟加载,所有这一切都正常。然后Item.Car.Color为null。完善。但是,我非常担心为大量结果集做太多的数据库查询,这当然是可能的。

避免过多数据库查询的一个解决方案是从数据源查询中返回一个匿名类型,其中包含网格所需的所有特定相关信息位,并将所有“Item”样式绑定转换为良好的'ol Eval() 。但后来我失去了强类型,以及Value Provider属性带来的简单性。我不想重写这一切。

我是对的,我必须选择其中一种吗?即使没有Color记录,如何设置查询以返回所有Car记录?如果我试着用.Include()来加载,我想我已经搞砸了。我需要像.IncludeWithNulls()或其他东西。

更新:想到这一点。我不知道这对于查询成本有多难看,但它确实有效。还有更好的方法吗?

var query = context.Cars.Include(x => x.Colors);
var query2 = context.Cars.Where(x => !context.Colors.Any(y => y.Color_ID == x.Color_ID);
return query.Union(query2);

1 个答案:

答案 0 :(得分:0)

问题是不正确的结束多样性。我真正需要的不是1..many而是0..many。这样,Entity Framework从.Include()生成左外连接而不是内连接。这是有道理的,上面的例子中可能没有实际的Color记录。令我感到困惑的是,在SQL数据库中,我从未将这些外键字段设置为可空,因为在创建时,它们总是需要有效的外键。所以我将它们设置为可空并修复了我的.edmx表,一切正常。我确实必须在这里和那里添加一些更多的空检查,例如我上面的问题,之前并不是绝对必要的,因为.Include现在引入了引用缺失相关实体的记录,但没什么大不了的。

所以我在数据库级别的非空检查中失败了,但是我在LINQ查询中获得了一些一致的逻辑,以了解这些表实际上是如何关联的,以及我期望得到什么。