Entity Framework (Linq) 中的左外连接。成员具体化为 Null
Left Outer Join in Entity Framework (Linq). Member materializing to Null
问题:
我可以执行左连接并验证 null
ed 元素吗?
终止数据库 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
。如果我使用三元运算符来验证 null
ed 值,应用程序将抛出以下异常
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
- 我试过使用
UseDatabaseNullSemantics
,我没想到会解决它,但至少有助于解决问题,但结果是 Failed
您引用的错误信息:
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
是值类型。与引用类型不同,它们不能是 null
。 here.
可以找到对引用类型与值类型的良好处理
当 .NET 首次出现时,基本上就是这样。后来,很明显这会非常不方便,因此 .net 设计人员加入了一个名为 nullable types 的新功能。这些允许绕过上述限制。在 C# 中,您通过指定值类型然后向其添加问号来引用可空类型,如下所示:System.Decimal?
或简单地 decimal?
。 decimal?
类型的字段将能够容纳 null
.
您需要告诉编译器您正在使用的类型,它无法自行正确识别。更改您的这行代码:
computed = rollout.Rollout
这样阅读:
computed = (decimal?)rollout.Rollout
这将表明 null 是一个有效值,您的代码将起作用。
一般来说,在 深入了解更复杂的内容(如 ORM 用法)之前,花一些时间学习基础知识会有所帮助。如果您不了解基础知识,当出现故障时,很难确定 是什么 损坏了 - 因为您没有掌握所有的拼图,但是一旦您了解了它们,通常答案显而易见。
问题:
我可以执行左连接并验证 null
ed 元素吗?
终止数据库 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
。如果我使用三元运算符来验证 null
ed 值,应用程序将抛出以下异常
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
- 我试过使用
UseDatabaseNullSemantics
,我没想到会解决它,但至少有助于解决问题,但结果是Failed
您引用的错误信息:
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
是值类型。与引用类型不同,它们不能是 null
。 here.
当 .NET 首次出现时,基本上就是这样。后来,很明显这会非常不方便,因此 .net 设计人员加入了一个名为 nullable types 的新功能。这些允许绕过上述限制。在 C# 中,您通过指定值类型然后向其添加问号来引用可空类型,如下所示:System.Decimal?
或简单地 decimal?
。 decimal?
类型的字段将能够容纳 null
.
您需要告诉编译器您正在使用的类型,它无法自行正确识别。更改您的这行代码:
computed = rollout.Rollout
这样阅读:
computed = (decimal?)rollout.Rollout
这将表明 null 是一个有效值,您的代码将起作用。
一般来说,在 深入了解更复杂的内容(如 ORM 用法)之前,花一些时间学习基础知识会有所帮助。如果您不了解基础知识,当出现故障时,很难确定 是什么 损坏了 - 因为您没有掌握所有的拼图,但是一旦您了解了它们,通常答案显而易见。