动态LINQ groupby并从ADO datatable中选择列并返回数据表

时间:2015-09-04 09:38:01

标签: linq dynamic

我有一个ADO数据表如下

tname   cname   rgname  schools mtext
tn1     cn1      rg1     1      mxt1
tn1     cn1      rg1     2      mxt1
tn1     cn1      rg1     3      mxt1
tn2     cn2      rg2     5      mxt2
tn2     cn2      rg2     8      mxt2
tn2     cn2      rg2     3      mxt2
tn3     cn1      rg1     7      mxt1
tn3     cn1      rg1     4      mxt1

我想通过以逗号分隔的方式对学校进行分组和连接,从而生成上表中的表格。结果应如下所示

tname   cname   rgname  schools mtext
tn1     cn1     rg1     1,2,3   mxt1
tn2     cn2     rg2     5,8,3   mxt2
tn3     cn1     rg1     7,4     mxt1

我只在运行时通过列知道组。我还希望将结果作为类似数据表,因为有更多列(最多15个)。 S可以使用动态组by并选择lambda表达式。

我已经实现了动态组的逻辑,但动态选择让我感到不安。

    var result = from o in DT.AsEnumerable()
         group o by new
         {
           cname = groupByCname? o.Field<string>("cname") : null,
           tname = groupByTname? o.Field<string>("tname") : null,
           rgname = groupByRGname? o.Field<string>("rgname") : null,
           mtext = groupByMtext? o.Field<string>("mtext") : null,
         } into g
       select new
        {
        //Here i want to select all columns from DT and have schools as
        // comma separated
         schools = String.Join(",",g.Select(x=>x.Field<string>  ("Schools")).ToArray())
       };

感谢您的帮助

1 个答案:

答案 0 :(得分:0)

我已对您的代码进行了一些修改。这可能不是最好的方法,但它确实为您提供了所需的内容。

var result = from row in
        (from t in
            (from o in dt.AsEnumerable()
             join u in dt.AsEnumerable()
             on o.Field<string>("tname") equals u.Field<string>("tname")
             select new
             {
                 o,
                 u = String.Join(",", u.Field<string>("schools"))
              })
              group t by new
              {
                  tname = t.o.Field<string>("tname"),
                  cname = t.o.Field<string>("cname"),
                  rgname = t.o.Field<string>("rgname"),
                  mtext = t.o.Field<string>("mtext")
              } into gcs
              select new
              {
                  rows = gcs.Select(x => x.o).First(),
                  schools = gcs.Select(x => x.u).Take(gcs.Key.tname.Count())
              })
    select row;

DataTable resultTable = new DataTable();
resultTable = dt.Clone();

foreach (var item in result)
{
    DataRow row = resultTable.NewRow();

    for (int i = 0; i < item.rows.ItemArray.Length; i++)
    {
        if (row.Table.Columns[i].ToString() == "schools")
        {
            row[i] = string.Join(", ", item.schools.ToList());
        }
        else
        {
            row[i] = item.rows.ItemArray[i];
        }
    }

    resultTable.Rows.Add(row);
}