如果相关实体已被删除,则include()不会加载记录



我有一个数据库1..两个表之间有许多关系,称为Color和Car。一种颜色与…许多人有汽车。在我的例子中,关键是可以随时删除颜色。没有级联删除,所以如果一个Color被删除,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为空。完美的。然而,我非常担心为一个庞大的结果集做太多的数据库查询,这当然是可能的。

避免过度db查询的一个解决方案是从数据源查询返回一个匿名类型,其中包含我需要的网格的所有特定相关信息位,并将所有"Item"样式绑定转换为良好的Eval()。但是这样我就失去了强类型和值提供程序属性带来的简单性。我可不想把这些都重写一遍。

我是对的,我必须选择一个还是另一个?我如何塑造我的查询,以返回所有的Car记录,即使没有Color记录?我想我搞砸了,如果我试图急于加载。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);

问题是终端多重性不正确。我真正需要的不是我…很多,但是很多。这样,实体框架就会从. include()中生成一个左外连接,而不是一个内连接。这是有道理的,在上面的例子中可能没有实际的Color记录。让我感到困惑的是,在SQL数据库中,我从来没有将这些外键字段设置为空,因为在创建时,它们总是需要一个有效的外键。因此,我将它们设置为可空的,并修复了我的。edmx表,一切都在工作。我确实必须在这里和那里添加一些空检查,例如我上面的问题,这在以前不是严格必要的,因为. include现在正在拉入引用缺失相关实体的记录,但没有什么大不了的。

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

最新更新