1

我知道可能有 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;
}

这是我不清楚如何进行的地方,即使我在正确的轨道上。谢谢你让我走上正轨。

4

1 回答 1

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方法(也可在 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接口。

于 2013-07-18T13:34:45.000 回答