2013-07-01 3 views
1

나는 기본적으로 쿼리 (가짜 테이블 이름에서이 작업을 수행하려고하지만 내가 사용하고 스키마와 정확히 같은 것을 그것을 좁혀했습니다null 값을 결합 할 때 왜이 중첩 평균은 작동하지 않습니까?

from v in db.Vehicles 
let avgVehicleModelMilesDriven = db.Vehicles.Where(av => av.ModelId == v.ModelId) 
              .Average(av => av.MilesDriven) 
select new 
{ 
    v.Id, 
    v.ModelId, 
    v.MilesDriven, 
    avgVehicleModelMilesDriven 
} 

내가 기대하고있어 결과 등 :

| Id | ModelId | MilesDriven | AverageModelMilesDriven | 
    1 1   10,000  15,000 
    2 1   20,000  15,000 
    3 2   15,000  15,000 

위의 작품 좋은,하지만 내가 일을 나누기 스키마 변경을 소개하자 ModelId가 널 (NULL)이 될 수 있다고 가정 지금과 같은 결과를 기대 :..

| Id | ModelId | MilesDriven | AverageModelMilesDriven | 
    1 1   10,000  15,000 
    2 1   20,000  15,000 
    3 2   15,000  15,000 
    4 null  5,000   5,000 
,691,363을210

대신 다음 예외가 발생합니다 : The null value cannot be assigned to a member with type System.Double which is a non-nullable value type.. 이것은 나에게 내가 평균하려고하는 콜렉션에는 어떤 값도 없다는 것을 알려준다.

| Id | ModelId | MilesDriven | AverageModelMilesDriven | 
    1 1   10,000  15,000 
    2 1   20,000  15,000 
    3 2   15,000  15,000 
    4 null  5,000   null 

하는 것은 이해가 안 : 나는 같은 잘못된 결과와 끝까지

db.Vehicles.Where(av => av.ModelId == v.ModelId) 
      .Average(av => (int?)av.MilesDriven) 

:이 작업을 얻을 수있는 유일한 방법은 지금과 같은 널 (NULL) int에 평균 선택된 값을 캐스팅입니다 그 타입의 적어도 1 대의 차량이 존재하기 때문에 이것이있을 수있는 방법. 그렇지 않으면 그 타입을 위해 평균을 얻으려고하지 않을 것이다. 나는 또한 조인을 통해이를 표현하려고 시도했지만 동일한 결과를 얻는다. 나는 명백한 것을 놓치고 있는가? 두 가지 쿼리에서이 작업을 수행 할 수 있지만이 경우 결과를 IQueryable로 유지해야합니다. 제공 할 수있는 도움에 미리 감사드립니다!

EDIT - 동일한 작업을 수행했지만 데이터베이스로 이동하지 않고 이러한 개체의 로컬 컬렉션에서 작업하는 작은 테스트 프로그램을 만들었습니다. 예상대로 작동했습니다. 생성하려고하는 SQL에 몇 가지 문제가 있다고 생각합니다. ModelId없이 레코드의 평균을 얻기 위해

Where(av => av.ModelId == v.ModelId 
     || (!av.ModelId.HasValue && !v.ModelId.HasValue)) 

:

+0

귀하의 명세서에서 생성되는 SQL은 무엇입니까? – Maciej

답변

1
는에 .Where 문을 변경

.

+0

그 트릭을 했어! 다른 누구에게나, SQL 생성에 문제가있는 것으로 보입니다. SQL에서 null 비교는 동일하게 작동하지 않지만 이렇게 작성하면 비교를 위해 'NOT NULL'을 사용하는 SQL을 생성해야하므로 예상대로 작동 할 수 있습니다. – Ocelot20