Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 单个LINQ表达式用于汇总数据集中的多个列_C#_.net_Linq - Fatal编程技术网

C# 单个LINQ表达式用于汇总数据集中的多个列

C# 单个LINQ表达式用于汇总数据集中的多个列,c#,.net,linq,C#,.net,Linq,我有一个数据集,它有几个行和列(数据集通常都有)。我需要在底部创建一个包含每列总和的计数行。我想用一个LINQ表达式来实现这一点,因为它将简化我的一系列代码。我可以得到单个列的总数,如下所示: var a = (from m in month where <some long expression> select m["BGCO_MINUTES"] as Decimal?).Sum(); var a=(从月份的m开始) 哪里 选择m[“BGCO_

我有一个
数据集
,它有几个行和列(数据集通常都有)。我需要在底部创建一个包含每列总和的计数行。我想用一个LINQ表达式来实现这一点,因为它将简化我的一系列代码。我可以得到单个列的总数,如下所示:

var a = (from m in month
         where <some long expression>
         select m["BGCO_MINUTES"] as Decimal?).Sum();
var a=(从月份的m开始)
哪里
选择m[“BGCO_MINUTES”]作为小数?).Sum();
但是,我还需要其他列的总计。我不想使用多个LINQ表达式,因为其中还有一个复杂的where子句,我正在使用各种表达式对几行进行计数,并且只想在这个集合中循环一次。我也不想自己手动循环遍历数据集并将总数相加,因为我正在创建许多这样的理货行,并且认为这样会更混乱

我想要的是一个匿名类型,它总共包含
BGCO\u分钟
800IB\u分钟
TSDATA\u分钟

有什么方法可以做到这一点吗?

使用而不是求和,因为它更灵活-您可以使用object(或简单的dictionary)在遍历每一行时保存各个列的求和

(未编译代码预发)

类对象{
公众优先;
公众持股第二;
}
已筛选的var=(从每月的m开始)
哪里
选择m;
聚合(新的SumObject(),(currentSum,item)=>{
currentSum.First+=项目First;
currentSum.Second+=第二项;
返回电流和;
});
使用而不是Sum,因为它更灵活-您可以使用object(或简单的dictionary)在遍历每一行时保存单个列的总和

(未编译代码预发)

类对象{
公众优先;
公众持股第二;
}
已筛选的var=(从每月的m开始)
哪里
选择m;
聚合(新的SumObject(),(currentSum,item)=>{
currentSum.First+=项目First;
currentSum.Second+=第二项;
返回电流和;
});
您可以这样做:

// run the filters once and get List<DataRow> with the matching rows
var list = (from m in month
            where <some long expression>
            select m).ToList();

// build the summary object
var result = new {
    BGCO_MINUTES = list.Sum(m => m["BGCO_MINUTES"] as Decimal?),
    _800IB_MINUTES= list.Sum(m => m["800IB_MINUTES"] as Decimal?),
}
//运行一次筛选器,并获取具有匹配行的列表
var list=(从每月的m开始)
哪里
选择m.ToList();
//生成摘要对象
var结果=新{
BGCO_MINUTES=list.Sum(m=>m[“BGCO_MINUTES”]作为十进制数?),
_800IB_分钟=list.Sum(m=>m[“800IB_分钟”]作为十进制数?),
}
这是假设where子句不仅输入时间长,而且计算代价高,这将在列表中每列迭代一次

如果您真的只想迭代列表一次,您可能可以使用,但代码不够优雅(在我看来):

//运行一次筛选器,并获取具有匹配行的列表
var a=(从每月的m开始)
哪里
选择m)
.聚合(新的{BGCO_分钟=(十进制?)0米,
_800IB_分钟=(十进制?)0m},
(ac,v)=>新的{BGCO_分钟数=ac.BGCO_分钟数+(十进制?)v[“BGCO_分钟数”],
_800IB_分钟=ac._800IB_分钟+(十进制?)v[“800IB_分钟”]};
正如我所说,我认为它不如第一个版本优雅,但它应该可以工作。尽管第一个版本需要一个与where子句(内存开销)匹配的值的临时副本,并且每个字段(CPU开销)都有一个列表,我认为它比后一个版本更具可读性-在使用不易理解的版本之前,确保性能差异是值得的。

您可以这样做:

// run the filters once and get List<DataRow> with the matching rows
var list = (from m in month
            where <some long expression>
            select m).ToList();

// build the summary object
var result = new {
    BGCO_MINUTES = list.Sum(m => m["BGCO_MINUTES"] as Decimal?),
    _800IB_MINUTES= list.Sum(m => m["800IB_MINUTES"] as Decimal?),
}
//运行一次筛选器,并获取具有匹配行的列表
var list=(从每月的m开始)
哪里
选择m.ToList();
//生成摘要对象
var结果=新{
BGCO_MINUTES=list.Sum(m=>m[“BGCO_MINUTES”]作为十进制数?),
_800IB_分钟=list.Sum(m=>m[“800IB_分钟”]作为十进制数?),
}
这是假设where子句不仅输入时间长,而且计算代价高,这将在列表中每列迭代一次

如果您真的只想迭代列表一次,您可能可以使用,但代码不够优雅(在我看来):

//运行一次筛选器,并获取具有匹配行的列表
var a=(从每月的m开始)
哪里
选择m)
.聚合(新的{BGCO_分钟=(十进制?)0米,
_800IB_分钟=(十进制?)0m},
(ac,v)=>新的{BGCO_分钟数=ac.BGCO_分钟数+(十进制?)v[“BGCO_分钟数”],
_800IB_分钟=ac._800IB_分钟+(十进制?)v[“800IB_分钟”]};

正如我所说,我认为它不如第一个版本优雅,但它应该可以工作。尽管第一个版本需要一个与where子句(内存开销)匹配的值的临时副本,并且每个字段(CPU开销)都有一个列表,我认为它比后一个版本可读性好得多-在使用不太容易理解的版本之前,确保性能差异是值得的。

Hmm..显然,当其他人在您写作时发布响应时(或者我错过了响应),不会给您一点弹出窗口。哦,好吧。我关于可读性的观点(除非涉及大量数据,否则性能差异可能很小)仍然有效。+1.是的,简单求和更具可读性。+您的示例没有额外的类,并且使用OP的对象。是的,我非常确定这是我将采用的方法。我从@AlexeiLevenkov发布的方法开始,它很快开始变得非常混乱:)数据不够大,无法满足任何性能方面的要求。嗯……显然,当其他人在您写作时发布响应(或者我错过了响应)时,不会给您一点弹出窗口。哦,好吧,我关于可读性的观点(以及性能差异可能是b
// run the filters once and get List<DataRow> with the matching rows
var a = (from m in month
         where <some long expression>
         select m)
        .Aggregate(           new { BGCO_MINUTES  = (decimal?)0m,
                                   _800IB_MINUTES = (decimal?)0m },
                    (ac,v) => new { BGCO_MINUTES  = ac.BGCO_MINUTES + (decimal?)v["BGCO_MINUTES"],
                                  _800IB_MINUTES = ac._800IB_MINUTES + (decimal?)v["800IB_MINUTES"] });