我正在寻找一个解决方案来置换linq查询并忽略大小写。我发现了这个:
m_context.Users.SingleOrDefault(u => string.Compare(u.UserName, username, StringComparison.InvariantCultureIgnoreCase) == 0);
它根据提供的用户名搜索用户对象,忽略大小写。它有效,这不是问题所在,但在分析代码时,我觉得很奇怪。我的意思是,在linq中,我们有字符串。比较(…,…,…),返回一个整数。那又怎样?linq(SingleOrDefault)是如何管理它的?
谢谢你的帮助。
您正在将谓词传递到SingleOrDefault
方法中。谓词的计算结果为true或false,此方法返回满足该谓词的序列中的单个元素。
u => string.Compare(x, y, StringComparison.InvariantCultureIgnoreCase) == 0
这是一个Func<User, bool>
谓词,这意味着它是一个接受User作为参数u
并返回布尔值作为string.Compare(...) == 0
求值结果的函数。然后返回满足此条件的用户序列中的单个元素。如果不止一个满足谓词,则为错误。如果满足谓词的值小于1,则获得该类型的默认值,对于引用类型,该值只是null。
非常粗略地将其视为
public static T SingleOrDefault<T>(this IEnumerable<T> sequence, Func<T, bool> predicate)
{
T foundItem = null;
int count = 0;
foreach (T item in sequence)
{
if (predicate(item)) // evaluates the u => string.Compare(...)
{
count += 1;
if (count > 1)
throw new InvalidOperationException("...");
foundItem = item;
}
}
return foundItem;
}
以上再次只是我对方法作用的粗略描述,而不是实际实现。如果你对linq-to-objects实现有兴趣进行更深入的研究,可以考虑阅读Jon Skeet的Edulinq系列,他在系列中介绍并重新实现了每一个(给予或接受)方法,并在此过程中对其进行了解释。同样,这不是库的实际源代码,但它非常有教育意义。
您有string.Compare(...) == 0
,即Boolean