私はこのクエリを持っています:
int maxShoeSize = Workers
.Where(x => x.CompanyId == 8)
.Max(x => x.ShoeSize);
maxShoeSize
会社8に労働者がまったくいない場合はどうなりますか?
更新:
例外ではなく0を取得するためにクエリを変更するにはどうすればよいですか?
maxShoeSize
?」と聞かれるのかわからない。あなたがすでにそれを試していたなら。
私はこのクエリを持っています:
int maxShoeSize = Workers
.Where(x => x.CompanyId == 8)
.Max(x => x.ShoeSize);
maxShoeSize
会社8に労働者がまったくいない場合はどうなりますか?
更新:
例外ではなく0を取得するためにクエリを変更するにはどうすればよいですか?
maxShoeSize
?」と聞かれるのかわからない。あなたがすでにそれを試していたなら。
回答:
int maxShoeSize = Workers.Where(x => x.CompanyId == 8)
.Select(x => x.ShoeSize)
.DefaultIfEmpty(0)
.Max();
ゼロインDefaultIfEmpty
は必要ありません。
Max()
、空のシーケンスを呼び出すとエラーが発生します。
私はこれが古い質問であり、受け入れられた回答が機能することを知っていますが、この質問は、そのような空のセットが例外になるか結果になるかについての私の質問に答えましたdefault(int)
。
ただし、受け入れられた答えは機能しますが、ここでは示していないIMHOの理想的なソリューションではありません。したがって、私はそれを探している人のために自分の答えでそれを提供しています。
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
結果が許可され、結果がに??
置き換えnull
られ0
ます。
編集
コメントから何かを明確にするために、Entity Frameworkは現在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);
うまくいけば、それが人々をさらに助けます。
DefaultIfEmpty
答えMax
は、が評価を行っていない場合にのみ機能します。
Select
ようMax
に集計関数を使用するつもりのときに、仲介者として使用するのは好きではありません。また、私は考えて鉱山はちょうどヌルを返すことで、空のセットに対処するだろうが生成されたSQLは、そうすることによって、余分な副選択クエリを使用することを(私はまだこれをテストしていません)。賛成票とフィードバックをありがとう!;)
ShoeSize
が実際に関連するUniform
エンティティにある場合、は使用せずWorkers.Where(x => x.CompanyId == 8).Select(x => x.Uniform).Max(x => x.ShoeSize)
、代わりにMax
関数全体の評価を保持しますWorkers.Where(x => x.CompanyId == 8).Max(x => x.Uniform.ShoeSize)
。クエリを効率的に構築する方法をEFが自由に決定できるように、クエリではできるだけ少ない方法を使用することを好みます。;-)
public static TResult MaxOrDefault<TElement, TResult>(this IQueryable<TElement> items, Expression<Func<TElement, TResult>> selector, TResult defaultValue = default) where TResult : struct => items.Select(selector).Max(item => (TResult?)item) ?? defaultValue;
その場合、Max()は何も返しません。
これは、発生しますと、InvalidOperationExceptionを元に要素が含まれていないからです。
InvalidOperationException
、リスト内のオブジェクトがnull非許容タイプであれば:docs.microsoft.com/en-us/dotnet/api/...
MaxはSystem.InvalidOperationException "シーケンスに要素が含まれていません"をスローします
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;
}