DataTable将结果分组在一行

编程入门 行业动态 更新时间:2024-10-26 15:27:29
本文介绍了DataTable将结果分组在一行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我有一个DataTable并且想要分组名称,姓氏和评论。其余的应该在同一行。 在我的代码中,首先我将ID的值作为标题,然后组织每个ID的属性值。我想要的是使用其ID值对相同的名称,姓氏和注释进行分组。 我的第一张表格如下所示:

ID名称Lastmame评论属性 1 kiki ha hello FF 3 lola mi hi AA 2 ka xe什么UU 2 kiki ha hello SS

我使用我的代码后:

姓名姓氏评论1 3 2 kiki ha hello FF lola mi hi AA ka xe什么UU kiki ha hello SS

我想要的是:

姓氏姓氏评论1 3 2 kiki ha hello FF SS lola mi hi AA ka xe什么UU

我的代码:

DataTable table1 = new DataTable (康德); table1.Columns.Add(Comment,typeof(String)); table1.Columns.Add(Name,typeof(String)); table1.Columns.Add(Lastname,typeof(String)); DataTable comment = new DataTable(Comment); comment.Columns.Add(ID,typeof(String)); comment.Columns.Add(Comment,typeof(String)); comment.Columns.Add(Attribute,typeof(String)); DataSet ds = new DataSet(DataSet); ds.Tables.Add(table1); ds.Tables.Add(comment); object [] o1 = {hello,kiki,ha}; object [] o2 = {lola,mi}; object [] o3 = {what,ka,xe}; object [] c1 = {1,hello,FF}; object [] c2 = {3,AA}; object [] c3 = {2,what,UU}; object [] c4 = {2,hello,SS}; table1.Rows.Add(o1); table1.Rows.Add(o2); table1.Rows.Add(o3); comment.Rows.Add(c1); comment.Rows.Add(c2); comment.Rows.Add(c3); comment.Rows.Add(c4); var results = from tb1 in comment.AsEnumerable()连接tb2在table1.AsEnumerable()在tb1.Field< string>(Comment)等于tb2。字段< string>(注释)选择新 { ID = tb1.Field< String>(ID), Name = tb2.Field< String> (Name), Lastname = tb2.Field< String>(Lastname),注释= tb1.Field< String>(Comment), Attribute = tb1。字段< String>(Attribute), }; DataTable result = LINQToDataTable(results); var products = result.AsEnumerable() .GroupBy(c => c [ID]) .Where(g =>!(g.Key是DBNull)) .Select(g =>(string)g.Key) .ToList(); var newtable = result.Copy(); products.ForEach(p => newtable.Columns.Add(p,typeof(string))); foreach(newtable.AsEnumerable()中的var row) { if(!(row [ID]是DBNull))row [(string)row [ ID]] = row [Attribute]; } newtable.Columns.Remove(ID); newtable.Columns.Remove(Attribute); var result11 = from newtable.AsEnumerable() group t1 by new {Name = t1.Field< String>(Name),LastName = t1.Field< String> (LastName),Comment = t1.Field< String>(Comment),} into grp select new { Name = grp.Key.Name, LastName = grp.Key.LastName,注释= grp.Key.Comment, //这里的东西};

使用System.Reflection;

public DataTable LINQToDataTable< T>(IEnumerable< T> varlist) { DataTable dtReturn = new DataTable(); //列名 PropertyInfo [] oProps = null; if(varlist == null)return dtReturn; foreach(T rec in varlist) { if(oProps == null) { oProps =((Type)rec.GetType ))GetProperties(); foreach(oProps中的PropertyInfo pi) {键入colType = pi.PropertyType; if((colType.IsGenericType)&&(colType.GetGenericTypeDefinition() == typeof(Nullable<))) { colType = colType.GetGenericArguments()[0]; } dtReturn.Columns.Add(new DataColumn(pi.Name,colType)); } } DataRow dr = dtReturn.NewRow(); foreach(oProps中的PropertyInfo pi) { dr [pi.Name] = pi.GetValue(rec,null)== null? DBNull.Value:pi.GetValue (rec,null); } dtReturn.Rows.Add(dr); } return dtReturn; }

解决方案

根据另一个答案:

一种方法是将所有结构中的变量列(如字典)

为此,请使用以下查询:

var variableColumnNames = newtable.Columns.Cast< DataColumn>() .Select(c => c.ColumnName) .Except(new [] { 名字,姓氏,评论)); var result11 = from newtable.AsEnumerable() group t1 by new { Name = t1.Field< String>(Name), LastName = t1.Field< String>(LastName),注释= t1.Field< String>(Comment),} into grp select new { grp.Key.Name, grp.Key.LastName, grp.Key.Comment, 值= variableColumnNames.ToDictionary( columnName => columnName, columnName => grp.Max(r => r.Field< String>(columnName)))};

如果您真的需要在类中具有可变数量的属性,那么这是不可能的如我所知,所以唯一可行的方法是将结果输出到另一个 DataTable (我们可以根据需要添加任意列)。

方法#2 - 使用动态

LINQ查询:

var result11 = from t1 in newtable.AsEnumerable() group t1 by new { Name = t1.Field< String>(Name), LastName = t1.Field< String>(LastName),注释= ),} into grp 选择CreateNewDynamicObject ( grp.Key.Name, grp.Key.LastName, grp.Key.Comment, variableColumnNames.ToDictionary( columnName => columnName, columnName => grp.Max(r => r。字段< String>(columnName)))); }

创建动态对象的新方法:

私有静态动态CreateNewDynamicObject( string name,string lastName,string comment,Dictionary< string,string> customProperties) { dynamic obj = new ExpandoObject(); obj.Name = name; obj.LastName = lastName; obj.Comment = comment; foreach(customProperties中的var prop)(obj as IDictionary< string,Object>)。Add(prop.Key,prop.Value ??); return obj; }

方法#3 - 输出到 DataTable

生成的 DataTable ( destinationTable )可以用作 DataGridView 的源代码:

var destinationTable = new DataTable(); foreach(newtable.Columns.Cast< DataColumn>()中的var列) destinationTable.Columns.Add(column.ColumnName,typeof(String)); var result11 = from newtable.AsEnumerable() group t1 by new { Name = t1.Field< String>(名称), LastName = t1.Field< String>(Lastname),注释= t1.Field< String>(Comment),} into grp 选择 variableColumnNames.ToDictionary( columnName => columnName, columnName => grp.Max(r => r.Field< String>(columnName)) ) .Concat(新字典< string,string> { {Name,grp.Key.Name}, {Lastname,grp.Key.LastName }, {评论,grp.Key.Comment} } ).ToDictionary(x => x.Key,x => x.Value); foreach(result11中的var row) { var newRow = destinationTable.NewRow(); foreach(vartableName in newtable.Columns.Cast< DataColumn>()。select(c => c.ColumnName)) newRow [columnName] = row [columnName]; destinationTable.Rows.Add(newRow); }

I have a DataTable and want to group Name, LastName and Comment. The rest should be in the same row. In my Code firstly i make ID's values as header and then organize the Attribute values to each ID. What I want here is to group the the same Name, Lastname and Comment with their ID values. My first Table looks like that:

ID Name Lastmame Comment Attribute 1 kiki ha hello FF 3 lola mi hi AA 2 ka xe what UU 2 kiki ha hello SS

After i use my code:

Name Lastname Comment 1 3 2 kiki ha hello FF lola mi hi AA ka xe what UU kiki ha hello SS

what i want to have is:

Name Lastname Comment 1 3 2 kiki ha hello FF SS lola mi hi AA ka xe what UU

My Code:

DataTable table1 = new DataTable("Kunde"); table1.Columns.Add("Comment", typeof(String)); table1.Columns.Add("Name", typeof(String)); table1.Columns.Add("Lastname", typeof(String)); DataTable comment = new DataTable("Comment"); comment.Columns.Add("ID", typeof(String)); comment.Columns.Add("Comment", typeof(String)); comment.Columns.Add("Attribute", typeof(String)); DataSet ds = new DataSet("DataSet"); ds.Tables.Add(table1); ds.Tables.Add(comment); object[] o1 = { "hello", "kiki", "ha" }; object[] o2 = { "hi", "lola", "mi" }; object[] o3 = { "what", "ka", "xe" }; object[] c1 = { 1, "hello", "FF" }; object[] c2 = { 3, "hi", "AA" }; object[] c3 = { 2, "what", "UU" }; object[] c4 = { 2, "hello", "SS" }; table1.Rows.Add(o1); table1.Rows.Add(o2); table1.Rows.Add(o3); comment.Rows.Add(c1); comment.Rows.Add(c2); comment.Rows.Add(c3); comment.Rows.Add(c4); var results = from tb1 in comment.AsEnumerable() join tb2 in table1.AsEnumerable() on tb1.Field<string>("Comment") equals tb2.Field<string>("Comment") select new { ID = tb1.Field<String>("ID"), Name = tb2.Field<String>("Name"), Lastname = tb2.Field<String>("Lastname"), Comment = tb1.Field<String>("Comment"), Attribute = tb1.Field<String>("Attribute"), }; DataTable result = LINQToDataTable(results); var products = result.AsEnumerable() .GroupBy(c => c["ID"]) .Where(g => !(g.Key is DBNull)) .Select(g => (string)g.Key) .ToList(); var newtable = result.Copy(); products.ForEach(p => newtable.Columns.Add(p, typeof(string))); foreach (var row in newtable.AsEnumerable()) { if (!(row["ID"] is DBNull)) row[(string)row["ID"]] = row["Attribute"]; } newtable.Columns.Remove("ID"); newtable.Columns.Remove("Attribute"); var result11 = from t1 in newtable.AsEnumerable() group t1 by new { Name = t1.Field<String>("Name"), LastName = t1.Field<String>("LastName"), Comment = t1.Field<String>("Comment"), } into grp select new { Name = grp.Key.Name, LastName = grp.Key.LastName, Comment = grp.Key.Comment, //Something here };

using System.Reflection;

public DataTable LINQToDataTable<T>(IEnumerable<T> varlist) { DataTable dtReturn = new DataTable(); // column names PropertyInfo[] oProps = null; if (varlist == null) return dtReturn; foreach (T rec in varlist) { if (oProps == null) { oProps = ((Type)rec.GetType()).GetProperties(); foreach (PropertyInfo pi in oProps) { Type colType = pi.PropertyType; if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>))) { colType = colType.GetGenericArguments()[0]; } dtReturn.Columns.Add(new DataColumn(pi.Name, colType)); } } DataRow dr = dtReturn.NewRow(); foreach (PropertyInfo pi in oProps) { dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue (rec, null); } dtReturn.Rows.Add(dr); } return dtReturn; }

解决方案

Based on the comments to this other answer:

One approach would be to stuff all the variable columns in a structure (like a dictionary).

In order to do this, use the following query:

var variableColumnNames = newtable.Columns.Cast<DataColumn>() .Select(c => c.ColumnName) .Except(new[]{"Name", "Lastname", "Comment"}); var result11 = from t1 in newtable.AsEnumerable() group t1 by new { Name = t1.Field<String>("Name"), LastName = t1.Field<String>("LastName"), Comment = t1.Field<String>("Comment"), } into grp select new { grp.Key.Name, grp.Key.LastName, grp.Key.Comment, Values = variableColumnNames.ToDictionary( columnName => columnName, columnName => grp.Max(r => r.Field<String>(columnName))) };

If you really need to have a variable number of properties in the class, this is not possible as far as I know, so the only plausible way to do that is to output the result to another DataTable (to which we can add as many columns as we want).

Approach #2 - using dynamic

The LINQ query:

var result11 = from t1 in newtable.AsEnumerable() group t1 by new { Name = t1.Field<String>("Name"), LastName = t1.Field<String>("LastName"), Comment = t1.Field<String>("Comment"), } into grp select CreateNewDynamicObject ( grp.Key.Name, grp.Key.LastName, grp.Key.Comment, variableColumnNames.ToDictionary( columnName => columnName, columnName => grp.Max(r => r.Field<String>(columnName))) ); }

the new method that creates the dynamic object:

private static dynamic CreateNewDynamicObject( string name, string lastName, string comment, Dictionary<string, string> customProperties) { dynamic obj = new ExpandoObject(); obj.Name = name; obj.LastName = lastName; obj.Comment = comment; foreach (var prop in customProperties) (obj as IDictionary<string, Object>).Add(prop.Key, prop.Value ?? ""); return obj; }

Approach #3 - outputting to a DataTable

The resulting DataTable (destinationTable) can be used as a source for a DataGridView:

var destinationTable = new DataTable(); foreach (var column in newtable.Columns.Cast<DataColumn>()) destinationTable.Columns.Add(column.ColumnName, typeof(String)); var result11 = from t1 in newtable.AsEnumerable() group t1 by new { Name = t1.Field<String>("Name"), LastName = t1.Field<String>("Lastname"), Comment = t1.Field<String>("Comment"), } into grp select variableColumnNames.ToDictionary( columnName => columnName, columnName => grp.Max(r => r.Field<String>(columnName))) .Concat(new Dictionary<string, string> { {"Name", grp.Key.Name}, {"Lastname", grp.Key.LastName}, {"Comment", grp.Key.Comment} } ).ToDictionary(x => x.Key, x => x.Value); foreach (var row in result11) { var newRow = destinationTable.NewRow(); foreach (var columnName in newtable.Columns.Cast<DataColumn>().Select(c => c.ColumnName)) newRow[columnName] = row[columnName]; destinationTable.Rows.Add(newRow); }

更多推荐

DataTable将结果分组在一行

本文发布于:2023-07-09 00:22:04,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1082135.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:DataTable

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!