Programing

빈 쿼리 인 경우 최대 반환 값

crosscheck 2020. 6. 16. 08:20
반응형

빈 쿼리 인 경우 최대 반환 값


이 쿼리가 있습니다.

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

NB :의 쿼리 속도DefaultIfEmpty() 가 상당히 느려질 수 있습니다 . 제 경우에는와 간단한 쿼리였습니다 .DefaultIfEmpty(DateTime.Now.Date).

나는 그것을 프로파일하기에는 너무 게으르지 만 분명히 EF는 모든 행을 얻은 다음 Max()가치 를 취하려고했습니다 .

결론 : 때때로 처리 InvalidOperationException가 더 나은 선택 일 수 있습니다.


삼항 .Max()을 사용하여 술어를 처리하고 그 값을 설정할 수 있습니다.

// assumes Workers != null && Workers.Count() > 0
int maxShoeSize = Workers.Max(x => (x.CompanyId == 8) ? x.ShoeSize : 0);

You would need to handle the Workers collection being null/empty if that's a possibility, but it would depend on your implementation.


You can try this:

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

You could check if there are any workers before doing the Max().

private int FindMaxShoeSize(IList<MyClass> workers) {
   var workersInCompany = workers.Where(x => x.CompanyId == 8);
   if(!workersInCompany.Any()) { return 0; }
   return workersInCompany.Max(x => x.ShoeSize);
}

참고URL : https://stackoverflow.com/questions/6966680/max-return-value-if-empty-query

반응형