问题:
我是否可以执行左连接并验证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。结果类型的通用参数或查询必须使用可空类型。
工作解决方案:
我可以通过在最终加入之前终止数据库链接(使用slawek建议使用.ToList()
)来避免这些异常(即transactions1.ToList() and transactions2.ToList()
。但我希望避免使用.ToList()
,因为我需要使用DB表执行另一个连接,这不能在List上完成。
我的实验自SO帖子
UseDatabaseNullSemantics
我不希望解决此问题,但至少在解决方案中提供了帮助,但结果是 Failed
答案 0 :(得分:0)
您引用的错误消息:
转换为值类型'System.Decimal'失败,因为 具体化值为null。结果类型的通用参数 或者查询必须使用可空类型。
表示您正在尝试将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使用。如果您不了解基础知识,当某些内容破裂时,很难确定什么打破了 - 因为您没有拼图的所有部分,但是一旦您了解它们,通常答案是显而易见的