问题
I have the following data:
PK OrderNumber USERDEFFIELD
1 0001 10
2 0001 25
3 0002 20
4 0002 22
5 0002 NULL
6 0003 ABC123
The UserDefField column is of VARCHAR type in the database. Using LINQ, how can I get the SUM(UserDefField) per order? NULL and non-numeric values for UserDefField are to be considered as zero. The result I'm trying to get:
OrderNumber TotalQty
0001 35
0002 42
0003 0
If UserDefField is strictly nullable numeric field I know I would do this inside a foreach loop:
TotalQtyForThisOrder = orders.Sum(w => w.UserDefField ?? 0 );
But for a string field, what should be done? Thank you very much for the help.
回答1:
TotalQtyForThisOrder = orders.Sum( w = > {
int result;
Int32.TryParse(w.UserDefField, out result);
return result;
});
回答2:
Fundamentally, I'd say your schema is off: if you're treating a textual value as a number if it happens to be parsable that way, you're really fighting against sensible design.
I don't know how you'd be able to write a LINQ query to make that sum occur in the database. You'd probably want to write some custom conversion function, or perhaps a custom view which did the "try to parse it and return 0 otherwise" operation.
You can do it easily enough within LINQ to Objects:
x = orders.Select(y => y.UserDefField) // To just bring down the right values
.AsEnumerable()
.Sum(text => {
int result;
// We don't care about the return value... and
// it even handles null input. (In any error condition,
// "result" will be 0 afterwards.)
int.TryParse(text, out result);
return result;
});
... but I'd really recommend that you revisit your schema if you possibly can.
回答3:
I would use the Aggregate function like so:
var result = orders.Aggregate(new Dictionary<OrderIdType, int>(), (accumulator, item) => {
int quantity;
if (!int.TryParse(item.USERDEFFIELD, out quantity))
quantity = 0;
if (!accumulator.ContainsKey(item.OrderId))
accumulator[item.OrderId] = quantity;
else
accumulator[item.OrderId] += quantity;
return accumulator;
});
来源:https://stackoverflow.com/questions/8917303/linq-summing-numbers-stored-as-string