이 쿼리가 있습니다.
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은 추가 하위 선택 쿼리를 사용하여 추가 하위 선택 쿼리를 사용하고 null을 반환하여 빈 세트를 처리 한다고 생각합니다 (아직 테스트하지 않았습니다). 공감과 피드백에 감사드립니다! ;)
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
목록의 개체가 nullable이 아닌 형식 인 경우 에만 발생합니다. docs.microsoft.com/en-us/dotnet/api/…
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
.
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;
}