В MS SQL то, что мне нужно делается так:
select sum(value1), avg(value2)
from MyTable
where not name is null
в C# (MyTable зачитывается в DataTable dtMyTable) искомые значения находятся так:
double @value1 = (from dr in dtMyTable.AsEnumerable()
where !Convert.IsDBNull(dr["name"])
select Convert.ToDouble(dr["value1"])).Sum();
double @value2 = (from dr in dtMyTable.AsEnumerable()
where !Convert.IsDBNull(dr["name"])
select Convert.ToDouble(dr["value2"])).Average();
Можно ли это как-то изящнее переписать? Мне не нравится что
from dr in dtMyTable.AsEnumerable()
where !Convert.IsDBNull(dr["name"]
повторяется (это для примера, реальное выражение может быть сложнее, условие WHERE сложнее и может быть больше функций MIN, MAX, COUNT итд, а не только две)
Спасибо
Здравствуйте, Аноним, Вы писали:
А>Можно ли это как-то изящнее переписать? Мне не нравится что
А>from dr in dtMyTable.AsEnumerable()
А>where !Convert.IsDBNull(dr["name"]
А>повторяется (это для примера, реальное выражение может быть сложнее, условие WHERE сложнее и может быть больше функций MIN, MAX, COUNT итд, а не только две)
var table = new DataTable {
Columns = {
{ "name", typeof(string) },
{ "value1", typeof(double) },
{ "value2", typeof(double) },
},
Rows = {
{ Convert.DBNull, -10, 20000 },
{ "a", 10, 20 },
{ "c", 1000, 2000 },
{ "b", -1, 200 },
},
};
var results = (
from row in table.AsEnumerable()
where !row.IsNull("name")
select new {
Value1 = row.Field<double>("value1"),
Value2 = row.Field<double>("value2"),
}
).Aggregate(new { Count = 0, Sum = default(double?), Min = default(double?), Max = default(double?), },
(acc, item) => new {
Count = acc.Count + 1,
Sum = (acc.Sum ?? 0) + (double?)item.Value1,
Min = item.Value1 >= acc.Min ? acc.Min : (double?)item.Value1,
Max = item.Value2 <= acc.Max ? acc.Max : (double?)item.Value2,
});
var average = results.Count > 0 ? results.Sum / results.Count : default(double?);