如果没有匹配,请获取First Single匹配元素或First

时间:2015-01-09 00:14:58

标签: c# sql-server linq dapper

是否可以在 LINQ 中编写一个漂亮的单行来获取第一个匹配的元素,或者是否与集合中的第一个元素不匹配?

E.g。你有一群鹦鹉,你想要黄鹦鹉,但如果没有黄鹦鹉 - 那么任何人都会这样做,就像这样:

Parrots.MatchedOrFirst(x => x.Yellow == true)

我试图避免双重访问SQL Server,我们在这种特殊情况下使用的ORM是Dapper

3 个答案:

答案 0 :(得分:3)

怎么样:

var matchedOrFirst = Parrots.FirstOrDefault(x => x.Yellow == true) 
    ?? Parrots.FirstOrDefault();

修改

对于结构体,这应该有效:

var matchedOrFirst = Parrots.Any(x => x.Yellow == true) 
    ? Parrots.First(x => x.Yellow == true)
    : Parrots.FirstOrDefault();

答案 1 :(得分:2)

编辑:这是SQL解决方案的linq

首先建立一个方便的扩展

public static T MatchedOrFirstOrDefault<T>(this IQueryable<T> collection, System.Linq.Expressions.Expression<Func<T, Boolean>> predicate)
{
  return (from item in collection.Where(predicate) select item)
                    .Concat((from item in collection select item).Take(1))
                    .ToList() // Convert to query result
                    .FirstOrDefault();
}

使用代码

var matchedOrFirst = Parrots.MatchedOrFirstOrDefault(x => x.Yellow);

答案 2 :(得分:0)

如果你想避免第二次SQL调用,并且因为需要分支逻辑,那么Dapper不太可能知道如何将LINQ查询转换为适当的SQL IIF,CASE或者你结束的任何其他SQL特定函数使用。

我建议您编写一个简单的存储过程来执行此操作并从Dapper中调用它。

根据其用途,如果此页面上只有一个或两个查询,并且与服务器位置相当接近(延迟明智),那么第二个简单的SELECT不会对整个应用程序造成太大影响。除非是在一个循环或其他东西,或者你的例子与关于第一个SELECT的成本的实际查询相比是微不足道的。