2013-07-18 4 views
1

Я знаю, что, возможно, существует намного более 100 способов сделать это, но пока я не вижу этого, я не могу понять, как это сделать. Для этого я использую linqpad. Прежде чем перейти на второй этап, мне нужно, чтобы эта часть работала!Проникновение через поля, чтобы получить сумму

Я подключился к базе данных SQL. Я запускаю запрос для получения некоторых желаемых записей.

var DesiredSym = (from r in Symptoms 
where r.Status.Equals(1) && r.Create_Date < TimespanSecs 
select r).Take(5); 

Таким образом, в этом примере, я получить 5 «записи» по существу в моей переменной DesiredSym, как IQueryable (LINQPad говорит мне об этом)

DesiredSym содержит большое количество полей, в том числе ряд feilds, которые держат a int Month1_Used, Month2_Used, Month3_Used .... Month12_Use.

Так что я хочу пройти через DesiredSym и в основном получить сумму всех полей Monthx_Used.

foreach (var MonthUse in DesiredSym) 
{ 
    // get sum of all fields where they start with MonthX_Used; 
} 

Здесь я не знаю, как действовать, или даже если я на правильном пути. Спасибо, что помог мне на правильном пути.

ответ

2

Поскольку у вас есть статическое количество полей, я рекомендовал бы это:

var DesiredSym = 
    (from r in Symptoms 
    where r.Status.Equals(1) && r.Create_Date < TimespanSecs 
    select retireMe) 
    .Take(5); 

var sum = DesiredSym.Sum(s => s.Month1_Use + s.Month2_Use + ... + s.Month12_Use); 

Вы могли использовать отражение, но это будет значительно медленнее и требует больше ресурсов, так как вы сначала нужно вывести весь набор результатов в память. Но только ради аргумента, это будет выглядеть примерно так:

var t = DesiredSym.GetType().GenericTypeArguments[0]; 
var props = t.GetProperties().Where(p => p.Name.StartsWith("Month")); 
var sum = DesiredSym.AsEnumerable() 
        .Sum(s => props.Sum(p => (int)p.GetValue(s, null))); 

Или это, что является более сложным, использование отражения, но имеет преимущество по-прежнему выполняется на базе:

var t = DesiredSym.GetType().GenericTypeArguments[0]; 
var param = Expression.Parameter(t); 
var exp = t.GetProperties() 
      .Where(p => p.Name.StartsWith("Month")) 
      .Select(p => (Expression)Expression.Property(param, p)) 
      .Aggregate((x, y) => Expression.Add(x, y)); 
var lambda = Expression.Lambda(exp, param); 
var sum = DesiredSym.Sum(lambda); 

Теперь к этим методам (кроме третьего) для вычисления суммы в пакетах по 5, вы можете использовать MoreLINQ «s Batch метод (also available on NuGet):

var DesiredSym = 
    from r in Symptoms 
    where r.Status.Equals(1) && r.Create_Date < TimespanSecs 
    select retireMe; 

// first method 
var batchSums = DesiredSym.Batch(5, b => b.Sum(s => s.Month1_Use ...)); 

// second method 
var t = DesiredSym.GetType().GenericTypeArguments[0]; 
var props = t.GetProperties().Where(p => p.Name.StartsWith("Month")); 
var batchSums = DesiredSym.Batch(5, b => b.Sum(s => props.Sum(p => (int)p.GetValue(s, null)))); 

Оба эти метода будут немного медленнее и использовать больше ресурсов, поскольку вся обработка должна быть записана в память. По той же причине третий метод не будет работать, поскольку MoreLinq не поддерживает интерфейс IQueryable.

Смежные вопросы