循环通过领域得到总和

时间:2013-07-18 13:30:41

标签: c# linq for-loop sum

我知道可能有100种更简单的方法可以做到这一点,但在我看到之前,我无法理解如何去做。我正在使用linqpad。在我进入第2阶段之前,我需要让这部分工作!

我已连接到SQL数据库。 我正在运行查询以检索一些所需的记录。

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

所以,在这个例子中,我基本上在我的DesiredSym变量中检索了5个'记录'作为iQueryable(linqpad告诉我这个)

DesiredSym包含大量字段,包括一个包含Month1_Used,Month2_Used,Month3_Used ...... Month12_Use的int的数字字段。

所以我想遍历DesiredSym并基本上得到所有Monthx_Used字段的总和。

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

这是我不知道如何继续或即使我走在正确的轨道上的地方。谢谢你让我走上正轨。

1 个答案:

答案 0 :(得分: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个批次的总和,您可以使用MoreLINQBatch方法(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接口。

相关问题