连接组合键时出现InvalidOperationException异常
本文关键字:InvalidOperationException 异常 组合 连接 | 更新日期: 2023-09-27 18:17:00
我有一个LINQ查询,在调用ToList()时在运行时抛出InvalidOperationException,我试图找出一种绕过它的方法,如果可能的话,而不必将连接分解成单独的where子句。
下面示例中的问题行是3和4。Loan_id是不可空类型的decimal, ti_disb_id是不可空类型的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异常未被用户代码处理
转换为值类型'Int16'失败,因为物化值为空。结果类型的泛型参数或查询必须使用可空类型。
提前感谢!
继续Garrison的评论,我建议您使用context Log属性。打开StreamWriter
,分配给context.Log
。它将给出在数据库上运行的确切SQL查询,您可以运行它并查看问题所在。
您可能需要再次查看您的数据库。例外是说其中一个短裤返回为空(a.ti_disb_id
或a.ti_disb_id
)。如果需要,您可以在查询中放入if
语句或使用空合并操作符。
我认为把new {a.loan_id, a.ti_disb_id}
改成new { loan = a.loan_id, disb = a.ti_disb_id ?? 0}
可以解决你们的问题。空合并运算符基本上是说,如果这个值为空,那么使用提供的默认值。为了使用它,分配是必需的(我尝试只是做a.ti_disb_id ?? 0
,但它不会编译),这就是为什么我把属性名称。参考文档在这里
所以,长话短说,经过多次调试后,我发现问题是我使用了LEFT JOIN行为而不是INNER JOIN行为。
具体来说,对DefaultIfEmpty()的调用正在创建导致schedule_id为空值的行,schedule_id的类型为non-nullable short (Int16),导致异常。通过取出这些DefaultIfEmpty()调用,不包括坏的行,并且问题得到了解决,因为schedule_id将永远不会接收空值。