как красиво написать через LINQ
От: Аноним  
Дата: 29.05.13 00:28
Оценка:
В 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 итд, а не только две)

Спасибо
Re: как красиво написать через LINQ
От: _FRED_ Черногория
Дата: 29.05.13 09:20
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Можно ли это как-то изящнее переписать? Мне не нравится что

А>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?);
Help will always be given at Hogwarts to those who ask for it.
Re[2]: как красиво написать через LINQ
От: Аноним  
Дата: 29.05.13 09:49
Оценка:
Здравствуйте, _FRED_, Вы писали:
http://stackoverflow.com/questions/1107868/linq-min-max
Вроде третий ответ
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.