在 LINQ 中,是否有可能编写一个好的一行代码,以获取集合中的第一个匹配元素或如果没有匹配,则获取第一个元素?
例如,您有一组鹦鹉,您想要黄色的鹦鹉,但如果没有黄色的鹦鹉,则任何一个都可以,就像这样:
Parrots.MatchedOrFirst(x => x.Yellow == true)
我正在尝试避免向SQL Server发送双重请求,在这种特殊情况下我们使用的ORM是Dapper。
在 LINQ 中,是否有可能编写一个好的一行代码,以获取集合中的第一个匹配元素或如果没有匹配,则获取第一个元素?
例如,您有一组鹦鹉,您想要黄色的鹦鹉,但如果没有黄色的鹦鹉,则任何一个都可以,就像这样:
Parrots.MatchedOrFirst(x => x.Yellow == true)
我正在尝试避免向SQL Server发送双重请求,在这种特殊情况下我们使用的ORM是Dapper。
关于:
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();
?? Parrots.FirstOrDefault()
。 - IlianParrots.FirstOrDefault(x => x.Yellow == true) ?? Parrots.First()
,但是(我想我应该提到)我想避免多次与SQL Server的往返。 - user1249170编辑:这是一个Linq to SQL的解决方案
首先打造一个便捷的扩展
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);
如果您想避免第二个 SQL 调用,并且需要分支逻辑,那么 Dapper 不太可能知道如何将您提出的 LINQ 查询转换为适当的 SQL IIF、CASE 或其他 SQL 特定函数。
我建议您编写一个简单的存储过程来完成这项工作,并从 Dapper 中调用它。
不过,根据其使用情况,如果此页面已经有一两个查询,并且与服务器相对靠近(延迟方面),第二个简单的 SELECT 对整个应用程序的影响不会太大。除非它在循环中或者您的示例与第一个 SELECT 的成本相比微不足道。