C# 实体框架中的左外部联接(Linq)。成员物化为Null

C# 实体框架中的左外部联接(Linq)。成员物化为Null,c#,sql-server,linq,entity-framework,left-join,C#,Sql Server,Linq,Entity Framework,Left Join,问题: 我是否可以执行左连接并验证nulled元素,而不使用 终止数据库链接?如果是,我该怎么做 试用代码 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, Ba

问题:

我是否可以执行左连接并验证
null
ed元素,而不使用 终止数据库链接?如果是,我该怎么做

试用代码

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左键连接两个表。可以猜测,第二个表的某些值可能导致
null
。如果使用三元运算符验证
null
ed值,应用程序将抛出以下异常

DbIsNullExpression的参数必须引用基元、枚举或引用类型

在以下位置找到堆栈跟踪:

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

转换为值类型“System.Decimal”失败,因为具体化的值为null。结果类型的泛型参数或查询必须使用可为空的类型

在以下位置找到堆栈跟踪:

工作解决方案

我可以通过在最终联接(即,
transactions1.ToList()和transactions2.ToList()
)之前终止DB链接(使用建议的
.ToList()
)来避免这些异常。但是我希望避免使用
.ToList())
因为我需要执行另一个与DB表的连接,这在列表中是无法完成的

自SO发布以来我的实验

  • 我尝试过使用
    UseDatabaseNullSemantics
    ,我没有想到会解决它,但至少有助于解决问题,但结果是
    失败了

您引用的错误消息:

转换为值类型“System.Decimal”失败,因为 物化值为null。结果类型的泛型参数 或者查询必须使用可为空的类型

表示您正试图将
null
的值分配给
System.Decimal
类型的字段。这在.Net中是非法的。
System.Decimal
是一种值类型。与引用类型不同,这些值不能为
null
。可以找到关于引用类型与值类型的良好处理方法

当.NET第一次出现时,基本上就是这样。后来,很明显,这可能会非常不方便,因此.NET设计人员开发了一个名为的新功能。这允许绕过上述限制。在c#中,通过指定一个值类型,然后在其中添加一个问号来引用可空类型,如:
System.Decimal?
或干脆
decimal?
decimal?
类型的字段将能够保持
null

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

computed = rollout.Rollout
这样读:

computed = (decimal?)rollout.Rollout
这将表明null是一个有效值,并且您的代码可以工作


一般来说,在深入研究ORM的使用等更复杂的问题之前,花一些时间学习基础知识是有帮助的。如果你不知道基础知识,当一些东西坏了,很难确定是什么坏了——因为你没有拼图的所有部分,但一旦你知道了,答案通常是显而易见的。

错误消息您引用的:

转换为值类型“System.Decimal”失败,因为 物化值为null。结果类型的泛型参数 或者查询必须使用可为空的类型

表示您正试图将
null
的值分配给
System.Decimal
类型的字段。这在.Net中是非法的。
System.Decimal
是一种值类型。与引用类型不同,这些值不能为
null
。可以找到关于引用类型与值类型的良好处理方法

当.NET第一次出现时,基本上就是这样。后来,很明显,这可能会非常不方便,因此.NET设计人员开发了一个名为的新功能。这允许绕过上述限制。在c#中,通过指定一个值类型,然后在其中添加一个问号来引用可空类型,如:
System.Decimal?
或干脆
decimal?
decimal?
类型的字段将能够保持
null

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

computed = rollout.Rollout
这样读:

computed = (decimal?)rollout.Rollout
这将表明null是一个有效值,并且您的代码可以工作


一般来说,在深入研究ORM的使用等更复杂的问题之前,花一些时间学习基础知识是有帮助的。如果你不知道基础知识,当一些东西坏了,很难确定是什么坏了——因为你没有拼图的所有部分,但一旦你知道了,答案往往是显而易见的。

这是一个非常简单的问题但是有效的解决方案是,我应该说我知道可空类型,正如您在我的问题中看到的,我尝试通过测试
卷展栏
对象来避免空值。从您的回答中,我假设不能使用三元
?:
运算符来计算空值(当DB链接处于活动状态时)。但谢谢你,这是一个非常简单的解决方法。这是一个非常简单但有效的解决方案,我应该说我知道可空类型,正如你在我的问题中看到的,我尝试通过测试
卷展栏
对象来避免空值。根据你的回答,我假设不能使用三元
?:
oOperator(当DB链接处于活动状态时)。但谢谢您,这是一个非常简单的解决方法。