使用动态GroupBy子句的Linq实现

时间:2019-07-07 02:50:28

标签: linq

在下面的Linq语句中,我在尝试获取数据表字段(如“ ID”)并将其分配给row [“ ID”]时遇到“选择”错误。

//row["ID"] =  g.Field<decimal>("ID");

错误消息:

  

System.Linq.IGrouping<string,System.Data.DataRow>不包含“字段”的定义

var x = groupedDataRow
    .AsEnumerable()
    .Select(g =>
    {
        var row = dataTable.NewRow();
        //row["ID"] =  g.Field<decimal>("ID");
        row["AMT"] = g.Sum(r => r.Field<decimal>("AMT"));
        row["PERCENTAGE"] = g.Sum(r => r.Field<decimal>("PERCENTAGE"));
        return row;
    }).CopyToDataTable();

如何检索数据表字段(例如“ ID”),以便可以将其分配给Select语句中的row [“ ID”]?

Linq示例

 public class Program
 {
    static StringBuilder stringBuilder = new StringBuilder();
    public static String GroupData(DataRow dataRow)
    {
        String[] columnNames = new[] {"ID","COL1", "COL2"};
        stringBuilder.Remove(0, stringBuilder.Length);
        foreach (String column in columnNames)
        {
            stringBuilder.Append(dataRow[column].ToString());
        }
        return stringBuilder.ToString();
    }

    public static void Main()
    {
         DataTable dataTable = new DataTable("MyTable");

        DataColumn dc2 = dataTable.Columns.Add("ID", typeof(decimal));  
        dataTable.Columns.Add("AMT", typeof(decimal));  
        dataTable.Columns.Add("PERCENTAGE", typeof(decimal));  
        dataTable.Columns.Add("COL1", typeof(String));  
         dataTable.Columns.Add("COL2", typeof(String));

        dataTable.Rows.Add(000, 400,100,"sss","vvv");  
        dataTable.Rows.Add(888, 400, 100,"qqq","fff");  
        dataTable.Rows.Add(000, 300, 100,"eee","aaa");  
        dataTable.Rows.Add(000, 300, 100,"eee","aaa");  
        dataTable.Rows.Add(000,400,100,"sss","vvv");  




         EnumerableDataRowList<DataRow> enumerableRowCollection = new EnumerableDataRowList<DataRow>(dataTable.Rows);

        Func<DataRow, String> groupingFunction = GroupData;
        var groupedDataRow = enumerableRowCollection.GroupBy(groupingFunction);

        var x = groupedDataRow.AsEnumerable()
                .Select(g =>
                        {
                            var row = dataTable.NewRow();
                            //row["ID"] =  g.Field<decimal>("ID");
                            row["AMT"] = g.Sum(r => r.Field<decimal>("AMT"));
                            row["PERCENTAGE"] = g.Sum(r => r.Field<decimal>("PERCENTAGE"));
                            return row;
                        }).CopyToDataTable();


        foreach(DataRow row in x.Rows)
        {
            Console.WriteLine(row["ID"].ToString() + " " + row["COL1"].ToString() + " " + row["COL2"].ToString() + " " + row["AMT"].ToString() + " " + row["PERCENTAGE"].ToString()) ;
        }
    }


class EnumerableDataRowList<T> : IEnumerable<T>, IEnumerable
{
    IEnumerable dataRows;
    internal EnumerableDataRowList(IEnumerable items)
    {
        dataRows = items;
    }
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        foreach (T dataRow in dataRows)
            yield return dataRow;
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        IEnumerable<T> iEnumerable = this;
        return iEnumerable.GetEnumerator();
    }
}

1 个答案:

答案 0 :(得分:0)

这是因为gIGrouping,没有Field成员。

您可以尝试以下方法:

  var x = groupedDataRow.AsEnumerable()
          .Select(g =>
          {
            var row = dataTable.NewRow();
            row["ID"] = g.Select(r => r.Field<decimal>("ID")).FirstOrDefault();
            row["AMT"] = g.Sum(r => r.Field<decimal>("AMT"));
            row["PERCENTAGE"] = g.Sum(r => r.Field<decimal>("PERCENTAGE"));
            return row;
          }).CopyToDataTable();

  var x = groupedDataRow.AsEnumerable()
          .Select(g =>
          {
            var row = dataTable.NewRow();
            row["ID"] = g.First().Field<decimal>("ID");
            row["AMT"] = g.Sum(r => r.Field<decimal>("AMT"));
            row["PERCENTAGE"] = g.Sum(r => r.Field<decimal>("PERCENTAGE"));
            return row;
          }).CopyToDataTable();

使用g.First()应该是安全的,因为如果一个组包含任何项目,则它只是一个组。