[C#] 빈 쿼리 인 경우 최대 반환 값

이 쿼리가 있습니다.

int maxShoeSize = Workers
    .Where(x => x.CompanyId == 8)
    .Max(x => x.ShoeSize);

무엇을 할 것이다 maxShoeSize회사의 8 전혀 근로자가없는 경우는?

업데이트 :
예외가 아닌 0을 얻기 위해 쿼리를 어떻게 변경할 수 있습니까?



답변

int maxShoeSize = Workers.Where(x => x.CompanyId == 8)
                         .Select(x => x.ShoeSize)
                         .DefaultIfEmpty(0)
                         .Max();

제로인 DefaultIfEmpty은 필요하지 않습니다.


답변

나는 이것이 오래된 질문이고 받아 들여진 대답이 효과가 있다는 것을 알고 있지만,이 질문은 그러한 빈 세트가 예외 또는 결과를 초래할 것인지에 대한 내 질문에 대답했습니다 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);

잘하면 그것은 사람들을 훨씬 더 도와줍니다.


답변

이 경우 Max () 는 아무것도 반환하지 않습니다.

그것은 올릴 경우 InvalidOperationException을 소스에 요소가없는 때문이다.


답변

int maxShoeSize = Workers.Where(x => x.CompanyId == 8)
                     .Select(x => x.ShoeSize)
                     .DefaultIfEmpty()
                     .Max();


답변

Linq to SQL 인 경우 사용하고 싶지 않습니다. Any() SQL 서버에 여러 쿼리가 발생 때문에 .

ShoeSize널 입력 가능 필드가 아닌 경우 를 사용 .Max(..) ?? 0하면 작동하지 않지만 다음은 사용됩니다.

int maxShoeSize = Workers.Where(x = >x.CompanyId == 8).Max(x => (int?)x.ShoeSize) ?? 0;

방출 된 SQL을 절대 변경하지는 않지만, 시퀀스가 ​​비어 있으면를 대신 대신를 Max()리턴하도록 변경하여 0 을 리턴 int?합니다 int.


답변

int maxShoeSize=Workers.Where(x=>x.CompanyId==8)
    .Max(x=>(int?)x.ShoeSize).GetValueOrDefault();

( ShoeSize유형 이라고 가정 int)

경우 WorkersDbSet또는 ObjectSet엔티티 프레임 워크에서 초기 쿼리는를 슬로우 InvalidOperationException하지만 빈 순서에 대해 불평하지만,이 값이 NULL이로 변환 할 수 없습니다 구체화 불평하지 int.


답변

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;
}