2013-06-04 4 views
0

ToList()를 호출 할 때 런타임에 InvalidOperationException을 throw하는 LINQ 쿼리가 있는데 가능한 한 조인을 해제 할 필요없이 해결 방법을 찾으려고합니다. 별도의 where 절로.복합 키로 결합 할 때 InvalidOperationException이 발생합니다.

문제의 줄은 아래 예에서 3과 4입니다. loan_id는 null이 허용되지 않는 유형 십진수이며, ti_disb_id는 null 허용 불가능 유형 short입니다. 이들을 별도의 문장으로 분리하면 ToList()를 호출 할 때 예외가 없습니다. 그러나 그것은 함께 더 이해가되는 것처럼 보이므로, 해결책이 있다면 그것을 듣고 싶습니다. :)

 var baseQuery = (from a in context.ti_disbursements 
         join b in context.disbursement_schedule 
          on new {a.loan_id, a.ti_disb_id} equals 
           new {b.loan_id, b.ti_disb_id} into ab 
          from b in ab.DefaultIfEmpty() 
         join c in context.business_associates 
          on a.ba_id equals c.ba_id into ac 
          from c in ac.DefaultIfEmpty() 
         join d in context.investor_loan 
          on b.loan_id equals d.loan_id into ad 
          from d in ad.DefaultIfEmpty() 
         join e in context.loan_information 
          on d.loan_id equals e.loan_id into ae 
          from e in ae.DefaultIfEmpty() 
         join f in context.loan_balances 
          on e.loan_id equals f.loan_id into af 
          from f in af.DefaultIfEmpty() 
         join g in context.ti_information 
          on e.loan_id equals g.loan_id into ag 
          from g in ag.DefaultIfEmpty() 
         select new 
         { 
          loan_id = a.loan_id, 
          ti_disb_id = a.ti_disb_id, 
          ti_freq_id = a.ti_freq_id, 
          ti_disbursements_stop_code = a.ti_stop_code, 
          tax_account_number = a.tax_account_number, 
          ti_disb_due_dt = b.ti_disb_due_dt, 
          ti_expire_dt = b.ti_expire_dt, 
          ti_disb_amt = b.ti_disb_amt, 
          schedule_id = b.schedule_id, 
          ba_name = c.ba_name, 
          inv_bank_cd = d.inv_bank_cd, 
          inv_cd = d.inv_cd, 
          inv_group_cd = d.inv_group_cd, 
          loan_name = e.loan_name, 
          prin_bal = f.prin_bal, 
          ti_bal = f.ti_bal, 
          ti_information_stop_code = g.ti_stop_cd, 
          non_escrowed_type = a.non_escrowed_type, 
          ba_type_id = a.ba_type_id, 
          bill_received_dt = a.bill_received_dt, 
         }); 

는 예외 메시지 :

InvalidOperation 예외는 구체화 된 값이 null이기 때문에 값 유형 캐스트 ​​'INT16가'실패 사용자 코드

에 의해 처리되지 않은이었다. 결과 유형의 제네릭 매개 변수 또는 쿼리가 null 가능 유형을 사용해야합니다.

미리 감사드립니다.

+0

데이터베이스에서 쿼리를 실행하여 결과 및 어떤 열이 null인지 확인합니다. null이 어디로 들어오는 지에 대한 힌트를 제공해야합니다. –

+0

@GarrisonNeely 예외는 이미 모든 정보를 제공합니다 (실제로 3 또는 4 번째 라인에서 던져 졌다고 가정하면). 이것은 'ti_disb_id' values는 null입니다. – evanmcdonnal

+0

@evanmcdonnal 그게 재밌 네요, 아무 값도 실제로 null입니다. 데이터베이스 값을 살펴본 결과 _supposed_라는 쿼리를 사용했습니다. _ 실제로 그 쿼리를 사용하든, 아직 알지 못했습니다. –

답변

0

많은 디버깅 후 짧은 이야기 만하면 INNER JOIN 동작 대신 LEFT JOIN 동작을 사용하고 있다는 것을 발견했습니다.

특히 DefaultIfEmpty()를 호출하면 예외를 발생시키는 null이 아닌 short (Int16) 유형의 schedule_id에 대한 null 값을 발생시키는 행이 생성됩니다. 이러한 DefaultIfEmpty() 호출을 가져옴으로써 잘못된 행이 포함되지 않고 schedule_id가 null 값을받지 않기 때문에 문제가 해결되었습니다.

1

Garrison의 의견에 계속해서 Log Log 속성을 사용하는 것이 좋습니다. StreamWriter을 열고 context.Log에 할당하십시오. 데이터베이스에서 실행되는 정확한 SQL 조회를 제공하며이를 실행하여. 제점을 볼 수 있습니다.

+1

예외는 ti_dsib_id 값 중 하나가 널 (NULL)이며 조회를 볼 필요가 없다는 것입니다. – evanmcdonnal

+0

고마워. – kobigurk

+0

@kobigurk 여전히 SQL을 잡는 방법을 알아 냈지만, 지금까지 내가 가지고있는 것은 다음과 같습니다. System.Data.Objects.ObjectQuery'1 [<>> f__AnonymousType13'20 [System.Decimal, System.Int16, System.Int32, System .Nullable'1 [System.Int16], System.String, System.Nullable'1 [System.DateTime], System.Nullable'1 [System.DateTime], System.Nullable'1 [System.Decimal], System.Int16 , System.String, System.String, System.String, System.Nullable'1 [System.Decimal], System.Nullable'1 [System.Decimal], System.Nullable'1 [System .Int16], System.String, System.Nullable'1 [System.Int16], System.Nullable'1 [System.DateTime]] –

1

데이터베이스를 다시 볼 수 있습니다. 예외는 반바지 중 하나가 null (a.ti_disb_id 또는 a.ti_disb_id)으로 돌아오고 있다는 것입니다. 필요한 경우 if 문을 쿼리에 넣거나 null 병합 연산자를 사용할 수 있습니다.

new {a.loan_id, a.ti_disb_id}new { loan = a.loan_id, disb = a.ti_disb_id ?? 0}으로 변경하면 문제가 해결 될 것이라고 생각합니다. null 통합 연산자는 기본적으로이 값이 null이면 제공된 기본값을 사용한다고 말합니다. 그것을 사용하기 위해서는, 할당이 필요합니다 (나는 단지 a.ti_disb_id ?? 0을 시도했지만 컴파일되지 않습니다). 그래서 속성 이름을 넣었습니다. 참조 문서는 here입니다.

+0

방금 ​​시도했습니다. 어떤 이유로, null-coalescing 연산자를 사용하여 컴파일하지 않을 것입니다. 그래서 3 진 연산자를 사용하도록 변경했습니다. 널 (NULL) 인 경우 0으로 대체하십시오. ti_disb_id 및 loan_id에서 테스트되었지만 예외가 여전히 발생합니다. 어쨌든 null을 사용할 수 없으므로 null 값을 가져서는 안됩니다. 가장 이상합니다. –

+0

@MacSigler는 불행합니다. 그 줄 중 하나에서 오류가 발생 했습니까? 나는 당신이'null' 값을 가지고 있다면 그 초기화 스타일을 사용하려는 어떤 시도도 실패 할 것이라고 믿는다. 컴파일러는 유형을 유추해야하고 null을 유추 할 수 없습니다. 나는 여전히 이것을 디버깅하려고한다면 select 문을 개인적으로보기 시작할 것이라고 생각한다. 또한 익명 형식을 작성하므로 null로 대입하면 오류가 발생합니다. – evanmcdonnal

+0

ti_disb_id가 아니라 schedule_id이므로 예외가 발생합니다. 그것을 더 보면서. –

관련 문제