Entity Framework (Linq) 中的左外连接。成员具体化为 Null

Left Outer Join in Entity Framework (Linq). Member materializing to Null

问题:

我可以执行左连接并验证 nulled 元素吗? 终止数据库 link?如果是,我该怎么做?

试用码

var transactions1 = (from tran in ctx.transactions
    group tran.Amount by new { tran.UserID, tran.LeaveID } into leave
    select new { UserID = leave.Key.UserID, LeaveID = leave.Key.LeaveID, Balance = leave.Sum() });

var transactions2 = (from tran in ctx.transactions
    where tran.Type == type && tran.FiscalYear == fiscal
    group tran.Amount by new { tran.UserID, tran.LeaveID } into leave
    select new { UserID = leave.Key.UserID, LeaveID = leave.Key.LeaveID, Rollout = leave.Sum() });

var computed = (from balance in transactions1
               join join_rollout in transactions2 on new { balance.UserID, balance.LeaveID } equals new { join_rollout.UserID, join_rollout.LeaveID } into rolls
               from rollout in rolls.DefaultIfEmpty()
               select new
               {
                   UserID = balance.UserID,
                   LeaveID = balance.LeaveID,
                   computed = rollout.Rollout
               }).ToList();

目标:

我正在尝试使用 linq 左连接两个 table。可以猜到,第二个 table 的某些值可能会导致 null。如果我使用三元运算符来验证 nulled 值,应用程序将抛出以下异常

The argument to DbIsNullExpression must refer to a primitive, enumeration or reference type.

PastBin

找到堆栈跟踪

如果我删除三元验证,应用程序会抛出以下异常

The cast to value type 'System.Decimal' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type.

PasteBin

找到堆栈跟踪

工作解决方案:

我可以通过在最终连接(即 transactions1.ToList() and transactions2.ToList() 之前终止数据库 link(使用 slawek 建议的 .ToList())来避免这些异常. 但是我希望避免使用 .ToList() 因为我需要执行另一个与数据库 table 的连接,这不能在列表上完成。

自 SO 以来我的实验 post

您引用的错误信息:

The cast to value type 'System.Decimal' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type.

表示您正在尝试将 null 的值分配给 System.Decimal 类型的字段。这在 .Net 中是非法的。 System.Decimal 是值类型。与引用类型不同,它们不能是 nullhere.

可以找到对引用类型与值类型的良好处理

当 .NET 首次出现时,基本上就是这样。后来,很明显这会非常不方便,因此 .net 设计人员加入了一个名为 nullable types 的新功能。这些允许绕过上述限制。在 C# 中,您通过指定值类型然后向其添加问号来引用可空类型,如下所示:System.Decimal? 或简单地 decimal?decimal? 类型的字段将能够容纳 null.

您需要告诉编译器您正在使用的类型,它无法自行正确识别。更改您的这行代码:

computed = rollout.Rollout

这样阅读:

computed = (decimal?)rollout.Rollout

这将表明 null 是一个有效值,您的代码将起作用。

一般来说,在 深入了解更复杂的内容(如 ORM 用法)之前,花一些时间学习基础知识会有所帮助。如果您不了解基础知识,当出现故障时,很难确定 是什么 损坏了 - 因为您没有掌握所有的拼图,但是一旦您了解了它们,通常答案显而易见。