C# c使用linq对数据表中的多个列进行分组
我在数据表中有三列:string、DateTime和decimal。我想按字符串和十进制列进行分组,对于分组的行,我想对十进制值求和。我知道如何进行求和部分,但是如何将数据表中的两个不同列分组 这是我目前为止无法正常工作的代码:C# c使用linq对数据表中的多个列进行分组,c#,linq,datatable,group-by,multiple-columns,C#,Linq,Datatable,Group By,Multiple Columns,我在数据表中有三列:string、DateTime和decimal。我想按字符串和十进制列进行分组,对于分组的行,我想对十进制值求和。我知道如何进行求和部分,但是如何将数据表中的两个不同列分组 这是我目前为止无法正常工作的代码: var newSort = from row in objectTable.AsEnumerable() group row by new {ID = row.Field<string>("resource_name"), tim
var newSort = from row in objectTable.AsEnumerable()
group row by new {ID = row.Field<string>("resource_name"), time1 = row.Field<DateTime>("day_date")} into grp
orderby grp.Key
select new
{
resource_name1 = grp.Key.ID,
day_date1 = grp.Key.time1,
Sum = grp.Sum(r => r.Field<Decimal>("actual_hrs"))
};
我认为你没有告诉我们全部情况。除了orderby不使用匿名类型(您提供的代码不会编译)之外,您的查询应该按照您想要的方式工作。我只是把这个放在LINQPad里:
var objectTable = new DataTable();
objectTable.Columns.Add("resource_name",typeof(string));
objectTable.Columns.Add("day_date",typeof(DateTime));
objectTable.Columns.Add("actual_hrs",typeof(decimal));
objectTable.Rows.Add(1, DateTime.Today, 1);
objectTable.Rows.Add(2, DateTime.Today, 2);
var newSort = from row in objectTable.AsEnumerable()
group row by new {ID = row.Field<string>("resource_name"), time1 = row.Field<DateTime>("day_date")} into grp
select new
{
resource_name1 = grp.Key.ID,
day_date1 = grp.Key.time1,
Sum = grp.Sum(r => r.Field<Decimal>("actual_hrs"))
};
newSort.Dump();
使用此代码
var newSort = from row in objectTable.AsEnumerable()
group row by new {ID = row.Field<string>("resource_name"), time1 = row.Field<DateTime>("day_date")} into grp
orderby grp.Key
select new
{
resource_name1 = grp.Key.ID,
day_date1 = grp.Key.time1,
Sum = grp.Sum(r => Convert.ToDecimal(r.ItemArray[2]))
};
对于希望在Vb.net中找到解决方案的用户,以下是一个示例:
Dim workTable As DataTable = New DataTable("Customers")
Dim workCol As DataColumn = workTable.Columns.Add("ID", Type.GetType("System.Int32"))
workTable.Columns.Add("Total", Type.GetType("System.Decimal"))
workTable.Columns.Add("Compra", Type.GetType("System.Decimal"))
Dim row As DataRow = workTable.NewRow()
row("id") = 2
row("total") = 1.5
row("compra") = 3
workTable.Rows.Add(row)
row = workTable.NewRow()
row("id") = 1
row("total") = 1.5
row("compra") = 3.3999999999999999
workTable.Rows.Add(row)
row = workTable.NewRow()
row("id") = 1
row("total") = 1.5
row("compra") = 5
workTable.Rows.Add(row)
Dim detalles As IEnumerable(Of DataRow) = workTable.AsEnumerable()
Dim query = From detalle In detalles.AsEnumerable() _
Group detalle By grupoClave = New With _
{ _
Key .C2 = detalle("id"), _
Key .C4 = detalle("total")} Into g = Group _
Select New With _
{ _
.Col2 = g(0).Field(Of Integer)("id"), _
.Col3 = g(0).Field(Of Decimal)("total"), _
.Col4 = g.Sum(Function(fact) fact.Field(Of Decimal)("compra")) _
}
For Each p In query
Console.WriteLine((p.Col2 & p.Col3 & p.Col4))
Next
编译器认为所有的对象都是相同的,所以每一行都被分组。你是说所有的对象都被放在一个大的组中,所以在newSort集合中只有一个项吗?是的,newSort只包含DataTable的最后一个元素。我觉得查询是正确的。您可以检查并重新检查您的输入吗?想知道如何根据其他两列组合的最小值从上面的每组中提取一行吗?@Si8:grp.OrderByg=>g.col1+g.col2.FirstOrDefault?
Dim workTable As DataTable = New DataTable("Customers")
Dim workCol As DataColumn = workTable.Columns.Add("ID", Type.GetType("System.Int32"))
workTable.Columns.Add("Total", Type.GetType("System.Decimal"))
workTable.Columns.Add("Compra", Type.GetType("System.Decimal"))
Dim row As DataRow = workTable.NewRow()
row("id") = 2
row("total") = 1.5
row("compra") = 3
workTable.Rows.Add(row)
row = workTable.NewRow()
row("id") = 1
row("total") = 1.5
row("compra") = 3.3999999999999999
workTable.Rows.Add(row)
row = workTable.NewRow()
row("id") = 1
row("total") = 1.5
row("compra") = 5
workTable.Rows.Add(row)
Dim detalles As IEnumerable(Of DataRow) = workTable.AsEnumerable()
Dim query = From detalle In detalles.AsEnumerable() _
Group detalle By grupoClave = New With _
{ _
Key .C2 = detalle("id"), _
Key .C4 = detalle("total")} Into g = Group _
Select New With _
{ _
.Col2 = g(0).Field(Of Integer)("id"), _
.Col3 = g(0).Field(Of Decimal)("total"), _
.Col4 = g.Sum(Function(fact) fact.Field(Of Decimal)("compra")) _
}
For Each p In query
Console.WriteLine((p.Col2 & p.Col3 & p.Col4))
Next