2009-02-23 3 views
17

이 코드가없는 경우 0을 반환의 예외가 발생합니다 (좋아, 그렇게하지,하지만 비슷한 : P) 여기합계는() 대신 행이

var dogs = Dogs.Select(ø => new Row 
    { 
      Name = ø.Name, 
      WeightOfNiceCats = ø.Owner 
       .Cats 
       .Where(æ => !æ.Annoying) 
       .Sum(æ => æ.Weight), 
    }); 

나는 모든 개를 통과하고 최대 합 개와 동일한 소유자를 가진 모든 비 귀찮은 고양이의 체중 (비 nullable 십진수로). 물론, 거의 모든 고양이는 귀찮은, 그래서이 오류 얻을 : 필드는 null이 될 수 사용 외래 키의

The null value cannot be assigned to a member with type System.Decimal which is a non-nullable value type.

없음을. 따라서 오류는 Where 절이 고양이를 반환하지 않을 때 발생합니다. 종종 그렇습니다. 하지만 어떻게 해결할 수 있을까요? 그 일이 발생하면 0을 반환하고 싶습니다. Where 절 후 DefaultIfEmpty()와 시도,하지만이 오류가 얻을 : 나는 이해할 것 같다

Object reference not set to an instance of an object.

합니다. 나는 Sum??을 추가했지만, 그것은 습관이 오류로 인해 컴파일도 물론 의미가

Operator '??' cannot be applied to operands of type 'decimal' and 'decimal'

합니다. 그래서 내가 무엇을 할 수 있니? 만약 아무 것도 합계가 없을 때 Sum이 0을 방금 돌려 주면 좋을 것입니다. 또는 어떤 종류의 문 SumOrZero. Linq2SQL과 함께 작동하는 SumOrZero 메서드를 만드는 것이 어려울까요?

+1

좋은 질문입니다. 이 문제는 MSDN에서 문서화되지 않은 것 같습니다. – Mykroft

답변

20

이것은 내가 지금과 결국 무엇을 :

.Sum(æ => (decimal?) æ.Weight) ?? 0.0M, 

이 매력처럼 작동합니다.

어떤 이유로 든 결코 null을 반환하지 않는다는 점을 제외하고는 Sum과 똑같이 작동하는 SumOrZero을 사용할 수 있습니다. 다른 사람들이 언급했듯이, 이것은 IEnumerable을 위해 꽤 쉽게 만들 수 있지만, IQuearyable을 만들기 위해 조금 더 칙칙한 것이므로 Linq2SQL 등에서 사용할 수 있습니다. 그래서 나는 지금 당장 그것을 남겨 둘 것입니다. 어느 날 누군가 지루해하고 SumOrZeroIQueryables으로 작성하면 모든 숫자 유형에 대해 Linq2SQL에서 작동합니다. D

+0

작은 오타 - '십진수'가 있어야합니다 * –

+1

@ 대니얼 맞습니다! 누군가 통지하고 통지하는 데 5 년이 걸렸습니다. – Svish

3

이미 주어진 (.Sum(æ => (decimal?) æ.Weight) ?? 0.0M) 트릭은이 시나리오가 데이터베이스에서 쿼리로 실행될 때 생각할 수있는 최선의 방법입니다. 약간 성가 시지만, 더 나쁜 것이 있습니다 ...

LINQ-to-Objects와 달리 기본 공급자가 매핑해야하므로 사용자 고유의 확장 방법을 추가 할 수 없습니다.

+0

. 그것은 내가 두려워했던 것이었다. – Svish

5

LINQ to Objects에서 쉽게 할 수 있습니다. LINQ to SQL을 사용하면 더 어려워 질 것입니다. Queryable.Sum이라는 확장 메서드를 작성할 수 있습니다.이 메서드는 정규식에서 작성된 식을 사용하여 nullable 형식으로 형 변환합니다. 네가 할 필요가있을 것 같아? ?? 0m 호출 코드에서 비록. 즉, 당신은 할 수 :

.SumOrNull(æ => æ.Weight) ?? 0M, 

.SumOrNull에 대한 서명이 될 것 여기서

public static decimal? SumOrNull<TSource, decimal>(this IQueryable<TSource>, 
    Func<TSource,decimal> projection) 

당신은 기본적으로 Queryable에서에서 지원하는 모든 값 유형이를 작성할 수 있습니다. 일 수 있으며 일반적으로 작성하고 리플렉션을 사용하여 쿼리 가능한 적절한 메소드를 호출하지만 너무 복잡합니다.

솔직히 말해서 나는 당신이 갖고있는 것과 가장 잘한다고 생각합니다.

+0

그러면 나는 내가 가지고있는대로 그냥 떠날 것 같아 .. – Svish

0

DefaultIfEmpty는 단일 요소가 0 인 IEnumberable을 반환하며 사용자가 필요로하는 것과 의미 상 동일합니다.

nullable 십진수를 가졌으므로 매개 변수 2 개를 사용하는 두 번째 버전의 메서드를 사용해야 할 것입니다.

+1

꽤 반대; 십진수는 null을 사용할 수 없습니다. LINQ-to-SQL 글리치에 대한 * 해결 방법 *은 계산을 위해 nullable로 만드는 것입니다. –

+0

그렇다면 더 쉽습니다. – leppie

+1

DefaultIfEmpty가 "개체 참조가 개체의 인스턴스로 설정되지 않았습니다." – Svish