在Where()子句中使用FirstOrDefault()

时间:2013-01-12 02:41:36

标签: c# sql-server linq entity-framework linq-to-sql

当我知道它应该返回至少一个时,我有一个没有返回结果的LINQ查询。我正在动态构建查询。在我到达过滤掉所有结果的行之前,我查看了调试器中的结果集,它包含数百行。在这一行之后,当它真的应该包含至少一个时,它包含0。

query = query.Where(x => 
    x.Lineages.FirstOrDefault().Sire.Contains(options.PedigreeContains));
在这种情况下,

'x'代表一个名为'Horse'的实体。 'options.PedigreeContains'只是一个字符串值。 Lineages表如下所示:

ID         HorseID         Sire       Dam        etc...

我甚至可以在调试器中拉出一个Horse实体(我知道应该返回一个),检查Lineages属性并查看它是否已完全填充,包括与我的搜索匹配的Sire值。因此,所有类似的SEEMS都应该正常工作,除了我正在使用的LINQ查询显然存在一些问题。

有没有人看到我正在做的事情本质上是错误的,这会导致我过滤掉我知道应该存在的结果?

编辑:为了澄清,这是一对一的关系。我知道Lineages对象存在,我知道只有一个,我知道它匹配。由于某种原因,它返回零结果,所以我认为我编写查询的方式可能有问题。如果该查询应该按其编写的方式工作(减去所有额外的“可能性”,如果不存在谱系,不止一个等等)那么它必须是我代码中其他地方的问题。

4 个答案:

答案 0 :(得分:1)

如果FirstOrDefault返回“默认”,该怎么办?你会得到NullReferenceException

答案 1 :(得分:1)

如果返回的第一个文件没有包含Lineages的{​​{1}},则您无法订购Sire。在这种情况下,无论option.PedigreeContains中的其他Sire是什么,结果集都将为空。

答案 2 :(得分:1)

实际上回答你的问题:不。您的查询没有任何内在错误。在查询构造,数据库结构或数据中,它必定是其他问题。

调试时,不是枚举和验证结果计数,而是复制query表达式值并查看生成的SQL的外观。您可以在更改IQueryable query之前和之后执行此操作。其他建议如@Jalalx使用.Any()来避免@John Saunders指出的内容。

答案 3 :(得分:0)

如果您使用FirstOrDefault(),那么您是不是可以选择许多公牛的第一个,所以如果后来的公牛匹配您找不到它的地方?

query = query.Where(x => 
    x.Lineages.FirstOrDefault(lineage => lineage.Sire.Contains(options.PedigreeContains))).Sire;