如果该行中的第一列为空,则entity framework为行返回null

我在我的Entity Framework模型中看到了一种奇怪的行为。 我有一个看起来像这样的查询:

var rows = ( from alarm in context.Alarms join temp in context.ListDetails on alarm.ListDetailId equals temp.ListDetailId into entries from entry in entries.DefaultIfEmpty() join read in context.Reads on alarm.ReadId equals read.ReadId join plate in context.Images on alarm.ReadId equals plate.ReadId where alarm.IActive == 1 && ! alarm.TransmittedAlarm where read.IActive == 1 where plate.IActive == 1 && plate.ImageTypeId == 2 select new { alarm, entry, read, plate } ).ToArray(); 

该查询按列名称按字母顺序返回所有列。 事实certificate,对于结果集中的几行,此列为NULL。 当我在调试器中展开rows变量时,我看到整行是空的!

编辑:一些澄清。

通过“第一列”,我的意思是第一行的第一列,即“SELECT A,B,C FROM …”,我的意思是A.实际上,entity framework构建的查询返回所有的连接结果集中的列按字母顺序排列,第一个按字母顺序排列可为空,对于某些行为空。

有问题的列不是主键; 如果它是主键,则不能为空。

当Entity Framework将返回数据的行处理为对象时,它会查看每行中第一列的值。 如果该列为null,则为该行返回null,而不是具有与该列对应的属性设置为null的对象。

我不相信这与左外连接有任何关系; 只是我的查询使用了一个。 但是,我没有做任何测试来validation这一点,所以这只是一个假设。

有没有人见过这个? 有人有解决方法吗?

托尼

我可以确认我遇到了同样的问题:当EF形成的SQL查询在结果的第一列中为null时,它返回null而不是实体。 这意味着完全遵循:

 using (var dc = new MyDbContext()) { var q = dc.Lands; //Lands is DbSet q = q.Where(criteria); //this leads to SQL query returning null in first column, confirmed by profiler var t = q.Single(); //t is now null } 

如果我们采用另一个在第一列中不会导致null条件,则t是正常的非null实体。

在我看来,它是EF中某种模糊的行为/错误。

更新

经过几个小时的探测,我发现了以下行为。 EF确实为在结果的第一列中具有NULL entites返回null (这会破坏预期的行为),但是它有几个关于首先放在选择列表中的列的概念。 因此,在使我的模型与我的数据库状态完全一致(这意味着表示所有NULLABLE数据库列并用optional替换required导航属性)之后 – 我正在使用Code First,所以有很多地方需要明确数据库 – 我’我设法让它工作。

这意味着您应该检查模型的商店级定义(取决于您使用的范例,基于设计器,或基于代码,它将是不同的地方)与您的数据库。

您在连接中使用DefaultIfEmpty 。 它的意思是

如果entries中没有与连接条件匹配的entriesalarm.ListDetailId equals temp.ListDetailId ),我希望您将一个ListDetail类型的默认值(为null )放入entries

在这种情况下,EF生成LEFT JOIN 。 实际上,这段代码是用Linq2Sql或EF生成LEFT JOIN的众所周知的方法。

如果表中没有行与JOIN条件匹配,则LEFT JOIN语句为表的所有列选择NULL值。 实际上,唯一重要的列是实体的PK列。 EF检查PK值是否为NULL ,确定不存在实体并将null放入entries 。 然后,您将此null作为结果的entry属性值。