简体   繁体   中英

What is the equivalent LINQ to SQL query expression of this SQL statement?

SQL query run 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

I tried following code in 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();

It throws an error:

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

There are a few cases where the straightforward SQL to C# translation gets accepted, but fails at run-time. In C#, set.DefaultIfEmpty().Select(n => n.Amount) , where n.Amount has type int , would have a result type IEnumerable<int> . It would fail with a NullReferenceException if set were empty, because in that case n would become null as well. Therefore, there is no reason why you'd need int? , since you can't ever get null as a result.

In SQL, it's not so easy. Retrieving a column of the default row introduced by LEFT JOIN is valid, and produces NULL .

But the C# code is expecting a value of type int , and an int can't be null .

You need to find some way to trick the type system so that you can specify how null should be handled. A simple cast suffices:

Change

Amount = n.Amount

to

Amount = (int?) n.Amount

Or, to turn null into 0 ,

Amount = (int?) n.Amount ?? 0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM