我有一个疑问:
int maxShoeSize = Workers
.Where(x => x.CompanyId == 8)
.Max(x => x.ShoeSize);
如果公司8根本没有工人,maxShoeSize中会有什么?
更新: 我如何改变查询,以获得0,而不是一个异常?
我有一个疑问:
int maxShoeSize = Workers
.Where(x => x.CompanyId == 8)
.Max(x => x.ShoeSize);
如果公司8根本没有工人,maxShoeSize中会有什么?
更新: 我如何改变查询,以获得0,而不是一个异常?
当前回答
int maxShoeSize = Workers.Where(x => x.CompanyId == 8)
.Select(x => x.ShoeSize)
.DefaultIfEmpty()
.Max();
其他回答
Max会抛出System。序列不包含元素
class Program
{
static void Main(string[] args)
{
List<MyClass> list = new List<MyClass>();
list.Add(new MyClass() { Value = 2 });
IEnumerable<MyClass> iterator = list.Where(x => x.Value == 3); // empty iterator.
int max = iterator.Max(x => x.Value); // throws System.InvalidOperationException
}
}
class MyClass
{
public int Value;
}
int maxShoeSize=Workers.Where(x=>x.CompanyId==8)
.Max(x=>(int?)x.ShoeSize).GetValueOrDefault();
(假设ShoeSize是int类型)
如果Workers是来自实体框架的DbSet或ObjectSet,您的初始查询将抛出InvalidOperationException,但不是抱怨一个空序列,而是抱怨物化值NULL不能转换为int。
你可以试试这个:
int maxShoeSize = Workers.Where(x=>x.CompanyId == 8).Max(x => x.ShoeSize) ?? 0;
你可以在.Max()中使用三元来处理谓词并设置它的值;
// assumes Workers != null && Workers.Count() > 0
int maxShoeSize = Workers.Max(x => (x.CompanyId == 8) ? x.ShoeSize : 0);
如果可能的话,您需要处理Workers集合为null/空,但这取决于您的实现。
我知道这是一个老问题,公认的答案是有效的,但这个问题回答了我关于这样一个空集是否会导致异常或默认(int)结果的问题。
然而,公认的答案,虽然它确实有效,但不是理想的解决方案,恕我直言,这里没有给出。因此,我在我自己的答案中提供了它,以使任何正在寻找它的人受益。
OP的原始代码是:
int maxShoeSize = Workers.Where(x => x.CompanyId == 8).Max(x => x.ShoeSize);
这是我如何写它来防止异常并提供默认结果:
int maxShoeSize = Workers.Where(x => x.CompanyId == 8).Max(x => x.ShoeSize as int?) ?? 0;
这导致Max函数的返回类型为int?,它允许空结果,然后??将null结果替换为0。
编辑 只是从评论中澄清一些事情,实体框架目前不支持as关键字,所以在使用EF时编写它的方式是:
int maxShoeSize = Workers.Where(x => x.CompanyId == 8).Max<[TypeOfWorkers], int?>(x => x.ShoeSize) ?? 0;
由于[TypeOfWorkers]可能是一个很长的类名,写起来很乏味,所以我添加了一个扩展方法来帮助解决这个问题。
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或任何其他您需要的值类型。使用这个扩展方法非常简单,只需传入选择器函数,并可选地包含一个用于null的值,该值默认为0。所以上面可以写成这样:
int maxShoeSize = Workers.Where(x => x.CompanyId == 8).MaxOrDefault(x => x.ShoeSize);
希望这能帮助到更多的人。