[C#] 구체화 된 값이 널이므로 값 유형 ‘Int32’로 캐스트하지 못했습니다.

다음 코드가 있습니다. 오류가 발생했습니다.

“구체화 된 값이 널이므로 값 유형 ‘Int32’로 캐스트하지 못했습니다. 결과 유형의 일반 매개 변수 또는 쿼리에서 널 입력 가능 유형을 사용해야합니다.”

CreditHistory 테이블에 레코드가없는 경우

var creditsSum = (from u in context.User
                  join ch in context.CreditHistory on u.ID equals ch.UserID
                  where u.ID == userID
                  select ch.Amount).Sum();

null 값을 허용하도록 쿼리를 수정하려면 어떻게해야합니까?



답변

linq-to-sql 쿼리는 코드로 실행되지 않고 SQL로 변환됩니다. 때때로 이것은 예기치 않은 동작을 일으키는 “누수 추상화”입니다.

이러한 경우 중 하나는 널 처리이며 다른 위치에 예기치 않은 널이있을 수 있습니다. ...DefaultIfEmpty(0).Sum(0)이 (아주 간단한) 경우에 도움이 될 수 있습니다. 여기서 요소와 sql의 SUM반환 값 이 없을 수 null있지만 c #은 0을 기대합니다.

보다 일반적인 접근 방식은 생성 된 SQL이 예기치 않은 널을 리턴 할 위험이있을 때마다 ??변환되는 사용 방법입니다 COALESCE.

var creditsSum = (from u in context.User
              join ch in context.CreditHistory on u.ID equals ch.UserID
              where u.ID == userID
              select (int?)ch.Amount).Sum() ?? 0;

첫 번째 캐스트하는 int?이 표현은 참으로 반환 할 수있는 C # 컴파일러에게 null, 비록 Sum()다시 표시를 int. 그런 다음 일반 ??연산자를 사용하여 null사례 를 처리합니다 .

이 답변을 바탕으로 LINQ to SQL 및 LINQ to Entities에 대한 세부 정보 가 포함 된 블로그 게시물 을 작성했습니다 .


답변

널 입력 가능 Amount필드 를 허용하려면 널 병합 연산자를 사용하여 널을 0으로 변환하십시오.

var creditsSum = (from u in context.User
              join ch in context.CreditHistory on u.ID equals ch.UserID
              where u.ID == userID
              select ch.Amount ?? 0).Sum();


답변

aggregate항목이 action을 수행하지 않는 함수를 사용 중입니다. linq 쿼리가 다음과 같은 결과를 제공하는지 확인해야합니다.

var maxOrderLevel =sdv.Any()? sdv.Max(s => s.nOrderLevel):0


답변

보기에서 선택하려고 할 때이 오류 메시지가 표시되었습니다.

문제는 최근에 뷰가 새로운 널 행 (SubscriberId 열)을 얻었고 EDMX (EF 데이터베이스 먼저)에서 업데이트되지 않았기 때문입니다.

컬럼이 작동하려면 널 입력 가능 유형이어야합니다.

var dealer = Context.Dealers.Where (x => x.dealerCode == dealerCode) .FirstOrDefault ();

보기 새로 고침 전 :

public int SubscriberId { get; set; }

보기 새로 고침 후 :

public Nullable<int> SubscriberId { get; set; }

EDMX에서 뷰를 삭제하고 다시 추가했습니다.

그것이 누군가를 돕기를 바랍니다.


답변

이 코드를 사용했으며 올바르게 응답합니다. 출력 값만 nullable입니다.

var packesCount = await botContext.Sales.Where(s => s.CustomerId == cust.CustomerId && s.Validated)
                                .SumAsync(s => (int?)s.PackesCount);
                            if(packesCount != null)
                            {
                                // your code
                            }
                            else
                            {
                                // your code
                            }


답변

이 질문에 이미 답변 된 것을 확인했습니다. 그러나 두 문장으로 나누려면 다음을 고려하십시오.

var credits = from u in context.User
              join ch in context.CreditHistory
                  on u.ID equals ch.UserID
              where u.ID == userID
              select ch;

var creditSum= credits.Sum(x => (int?)x.Amount) ?? 0;


답변

런타임 에이 코드로 Entity Framework 6 에서이 오류가 발생했습니다.

var fileEventsSum = db.ImportInformations.Sum(x => x.FileEvents)

LeandroSoares에서 업데이트 :

단일 실행에 이것을 사용하십시오 :

var fileEventsSum = db.ImportInformations.Sum(x => (int?)x.FileEvents) ?? 0

실물:

이것으로 바뀌었고 효과가있었습니다.

var fileEventsSum = db.ImportInformations.Any() ? db.ImportInformations.Sum(x => x.FileEvents) : 0;