SQL查询运行OK:
select o.OpName,isnull(Amount,0) from Setup_tblOperator o
left join
(
select t.opid,sum(isnull(t.Amount,0)) Amount from
Load_tblTransaction t
where cast(t.RequestTime as date)='2017-04-24'
group by t.opid
) t on t.OpId=o.OpId
where o.IsActive=1
我尝试在LINQ to SQL中使用代码:
var trans = (from o in mouDataEntities.Setup_tblOperator
join t in mouDataEntities.Load_tblTransaction
on o.OpId equals t.OpId into ot
from n in ot.Where(
t => DbFunctions.TruncateTime(t.RequestTime) ==
DbFunctions.TruncateTime(seldate))
.DefaultIfEmpty()
select new
{
Operator = o.OpName,
Amount= n.Amount
});
var gt = trans.GroupBy(t => t.Operator)
.Select(n => new { Operator = n.Key, Amount = n.Sum(a=>a.Amount) })
.ToList();
它会抛出错误:
转换为值类型'System.Int32'失败,因为已实现 value为null。结果类型的泛型参数或查询 必须使用可空类型。
答案 0 :(得分:3)
在某些情况下,直接的SQL到C#转换被接受,但在运行时失败。在C#中set.DefaultIfEmpty().Select(n => n.Amount)
,其中n.Amount
的类型为int
,其结果类型为IEnumerable<int>
。如果NullReferenceException
为空,则set
会失败,因为在这种情况下,n
也会变为null
。因此,您没有理由需要int?
,因为您无法获得null
。
在SQL中,它并不那么容易。检索LEFT JOIN
引入的默认行的列有效,并生成NULL
。
但是C#代码期望值int
的值,而int
不能null
。
您需要找到一些方法来欺骗类型系统,以便您可以指定应该如何处理null
。简单的演员阵容就足够了:
更改
Amount = n.Amount
到
Amount = (int?) n.Amount
或者,将null
变为0
,
Amount = (int?) n.Amount ?? 0