简体   繁体   中英

LINQ Datatable return 0 instead of null coalescing

I have the following LINQ statement which is calculating 3 values from a data table. Sometimes some of these values may contain null. How do i do the equivalent of coalescing the null to a 0.

var striko2scrap = from myrow in Scrap.AsEnumerable()
                   where myrow.Field<string>("MachineID") == "Striko 2"
                   group myrow by myrow.Field<string>("MachineID") == "Striko 2" into g
                   select new
                   {
                        TotalScrap = g.Sum(x => x.Field<int?>("Runners") ?? 
                                         0 + x.Field<int?>("HouseIngots") ?? 
                                         0 + x.Field<int?>("Other") ?? 
                                         0)
                   } ;

I have tried the ?? 0 in different places but when I debug I still get the same result. 在此输入图像描述

The problem you face is operator precedence. I think what you want to do is handle a null as 0 . That would be:

int? a = null;
int? b = 1;
int? c = 2;

int result = (a ?? 0) + (b ?? 0) + (c ?? 0); // 3

What you wrote is the equivalent of

int result = a ?? (0 + b) ?? (0 + c) ?? 0; // 1

So all you have to do is to modify the g.Sum(x => ...) and it should work as intended.

I personally like using the HasValue and Value properties of nullable value types, which would be:

select new
{
    TotalScrap = g.Sum(x => 
      (x.Field<int?>("Runners").HasValue ? x.Field<int?>("Runners").Value : 0 ) +
      (x.Field<int?>("HouseIngots").HasValue ? x.Field<int?>("HouseIngots").Value : 0 ) +
      (x.Field<int?>("Other").HasValue ? x.Field<int?>("Other").Value : 0 )
)};

But if you like the ?? notation you could use:

select new
{
    TotalScrap = g.Sum(x => 
      (x.Field<int?>("Runners") ?? 0 ) +
      (x.Field<int?>("HouseIngots") ?? 0 ) +
      (x.Field<int?>("Other") ?? 0 )
)};

Try this:

var striko2scrap = from myrow in Scrap.AsEnumerable()
                   where myrow.Field<string>("MachineID") == "Striko 2"
                   group myrow by myrow.Field<string>("MachineID") == "Striko 2" into g
                   select new
                   {
                        TotalScrap = g.Sum(x => 
                            (x.Field<int?>("Runners") ?? 0) +
                            (x.Field<int?>("HouseIngots") ?? 0) +
                            (x.Field<int?>("Other") ?? 0))
                   } ;

Have you tried

x.Field<int?>("Runners").Value ?? 0

or

x.Field<int?>("Runners").HasValue ? x.Field<int?>("Runners") : 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