在查询中使用FirstOrDefault()

时间:2011-11-03 10:47:12

标签: entity-framework entity-framework-4.1

有没有办法在复杂查询中使用FirstOrDefault()但是如果返回null值则不抛出异常?

我的查询:

contex.Table1.Where(t => t.Property == "Value").FirstOrDefault()
             .Object.Table2.Where(t => t.Property2 == "Value2").FirstOrDefault();

如果第一个表(Table1)上的查询未返回对象,则代码会抛出异常。有没有办法让它返回null?

3 个答案:

答案 0 :(得分:4)

SelectMany上试用Table2,而不使用中间FirstOrDefault()

context.Table1.Where(t1 => t1.Property1 == "Value1")
              .SelectMany(t1 => t1.Table2.Where(t2 => t2.Property2 == "Value2"))
              .FirstOrDefault();

此外,您可能希望使用SQL事件探查器来检查EF发送的SQL。我相信你问题中构造的查询将导致两个查询被发送到数据库;每个FirstOrDefault()一个。

答案 1 :(得分:1)

您可以构建自己的辅助函数,该函数采用IEnumerable

public static TSource CustomFirstOrDefault<TSource>(this IEnumerable<TSource> source)
{
    return source.FirstOrDefault() ?? new List<TSource>();
}

这将有效地返回一个空列表,当被调用时,提供你的Object属性中的代码可以处理空值,不会轰炸,导致你只是返回0项集合,而不是null

答案 2 :(得分:1)

只有Where的第一个查询才是数据库查询。一旦你应用像FirstOrDefault这样的“贪婪”运算符,查询就会被执行。第二个查询在内存中执行。如果Object.Table2是一个集合(它显然是)并且您没有启用延迟加载,则代码将崩溃,因为集合是null。如果启用了延迟加载,则会以静默方式执行第二个查询以加载集合 - 完整集合,并在内存中执行过滤。

您的查询应该看起来像@adrift的代码,它实际上只是一个数据库查询。