咨询区
Naor:
我有下面的一个查询:
int maxShoeSize = Workers.Where(x => x.CompanyId == 8).Max(x => x.ShoeSize);
如果 Workers.Where(x => x.CompanyId == 8)
没有查到任何 Workers 的话,上面的代码将会抛出异常。
现在的想法是:查不到的话 query 可以返回 0,但千万不要抛异常,我该如何修改上面的 query 呢?
回答区
Ron K.:
可以用 IEnumerable 的扩展方法 DefaultIfEmpty()
来避免这种尴尬,参考如下代码。
class Program{static void Main(string[] args){List<Worker> Workers = new List<Worker>(){new Worker(){ CompanyId=1, CompanyName="tweet", ShoeSize=10 },new Worker(){ CompanyId=2, CompanyName="google", ShoeSize=20 },};int maxShoeSize = Workers.Where(x => x.CompanyId == 8).Select(x => x.ShoeSize).DefaultIfEmpty(0).Max();Debug.WriteLine($"maxShoeSize={maxShoeSize}");}}class Worker{public int CompanyId { get; set; }public string CompanyName { get; set; }public int ShoeSize { get; set; }}
输出结果:
maxShoeSize=0
当然上面的 0
不是必须的,你可以改成其他的任何数。
CptRobby:
楼上那哥们提供的方案虽然可以正常运行,但看起来不是很入眼,可以改造成下面这样。
int maxShoeSize = Workers.Where(x => x.CompanyId == 8).Select(x => (int?)x.ShoeSize).Max() ?? 0;
代码看起来是不是有点冗长,最好的方式还是自定义一个 扩展方法
,如下代码所示:
public static int MaxOrDefault<T>(this IQueryable<T> source, Expression<Func<T, int?>> selector, int nullValue = 0)
{return source.Max(selector) ?? nullValue;
}
为了简单,这个扩展方法仅处理了 int
类型,你可以改成任意类型如:(long,double,...),接下来可以继续改造一下调用方。
int maxShoeSize = Workers.Where(x => x.CompanyId == 8).MaxOrDefault(x => x.ShoeSize);
希望我的答案可以帮助到更多人。
点评区
小编从来不敢在 Empty Collection
上做 Max,毕竟被坑的不是一次两次了,所以每次都提前判断集合是否存在值再执行 Max
,没想到还有神奇的扩展方法 DefaultIfEmpty
和 可空类型
可以帮忙搞定,感觉学的都忘了????????????。