Multiple on clause from DataTable to DataTable via LINQ
我有一个关于林肯的问题我想要内部联接两个数据表,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | DataTable dt1 = new DataTable(); DataTable dt2 = new DataTable(); dt1.Columns.Add("TEST1"); dt1.Columns.Add("TEST2"); dt1.Columns.Add("TEST3"); dt1.Columns.Add("TEST4"); dt2.Columns.Add("TEST2"); dt2.Columns.Add("TEST5"); dt2.Columns.Add("TEST6"); dt2.Columns.Add("TEST7"); for (int i = 0; i < 10; i++) { DataRow row = dt1.NewRow(); row["TEST1"] ="aaa"; row["TEST2"] = string.Format("bbb-{0}{1}{2}", i, (i % 2 == 0 ?"-" :""), (i % 2 == 0 ?"ddd" :"")); row["TEST3"] = i.ToString(); row["TEST4"] ="ddd"; dt1.Rows.Add(row); } for (int i = 0; i < 8; i++) { DataRow row = dt2.NewRow(); row["TEST2"] ="bbb"; row["TEST5"] = i.ToString(); row["TEST6"] = i % 2 == 0 ?"ddd" :""; row["TEST7"] ="sss"; dt2.Rows.Add(row); } |
DT1的描述是:
1 2 3 4 5 6 7 8 9 10 11 12 | TEST1 TEST2 TEST3 TEST4 --------------------------- aaa bbb-0-ddd 0 ddd aaa bbb-1 1 ddd aaa bbb-2-ddd 2 ddd aaa bbb-3 3 ddd aaa bbb-4-ddd 4 ddd aaa bbb-5 5 ddd aaa bbb-6-ddd 6 ddd aaa bbb-7 7 ddd aaa bbb-8-ddd 8 ddd aaa bbb-9 9 ddd |
号
DT2的描述是:
1 2 3 4 5 6 7 8 9 10 | TEST1 TEST5 TEST6 TEST7 ---------------------------- bbb 0 ddd sss bbb 1 sss bbb 2 ddd sss bbb 3 sss bbb 4 ddd sss bbb 5 sss bbb 6 ddd sss bbb 7 sss |
第一个问题是,我想加入DT1和DT2
1 2 3 4 5 6 7 8 9 10 | TEST2 TEST3 TEST7 --------------------------- bbb-0-ddd 0 sss bbb-1 1 sss bbb-2-ddd 2 sss bbb-3 3 sss bbb-4-ddd 4 sss bbb-5 5 sss bbb-6-ddd 6 sss bbb-7 7 sss |
。
所以我把代码写为下面的状态,我想把DT1和DT2加入到DT中。
1 2 3 4 5 6 7 8 9 10 11 | DataTable dt = new DataTable(); dt.Columns.Add("TEST2"); dt.Columns.Add("TEST3"); dt.Columns.Add("TEST7"); var result = from A1 in dt1.AsEnumerable() join A2 in dt2.AsEnumerable() on A1.Field<string>("TEST2") equals (A2.Field<string>("TEST2") +"-" + A2.Field<string>("TEST5") + (A2.Field<string>("TEST6") == string.Empty ?"-" : string.Empty) + A2.Field<string>("TEST6")) select new dt.LoadDataRow(new object[] { A1.Field<string>("TEST2"), A1.Field<string>("TEST3"), A2.Field<string>("TEST7") }, false); result.CopyToDataTable(); |
但是它不起作用~此外,我想更改test3和test7的列,test3将命名为x1,test3将命名为x5,所以最新一行的代码应该是
选择new dt.loadDataRow(new object[]a1.field("test2"),x1=a1.field("test3"),x5=a2.field("test7"),false);
这是另一个问题……我该怎么办?是吗?是吗?
在Internet上,您可以找到一个非常有用的功能,称为LinqToDataTable(如下所附),通过它,您可以将任何查询Linq转换为DataTable,从而保留查询产生的数据类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | public DataTable LINQToDataTable<T>(IEnumerable<T> varlist) { DataTable dtReturn = new DataTable(); PropertyInfo[] oProps = null; if (varlist == null) return dtReturn; foreach (T rec in varlist) { // Use reflection to get property names, to create table, Only first time, others will follow 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; } |
应轻松调用函数:
1 2 3 4 5 6 7 8 9 10 11 12 | var result = (from A1 in dt1.AsEnumerable() join A2 in dt2.AsEnumerable() on A1.Field<string>("TEST2") equals (A2.Field<string>("TEST2") +"-" + A2.Field<string>("TEST5") + (A2.Field<string>("TEST6") == string.Empty ?"-" : string.Empty) + A2.Field<string>("TEST6")) select new { TEST2 = A1.Field<string>("TEST2"), x1 = A1.Field<string>("TEST3"), x2 = A2.Field<string>("TEST7") }); DataTable dtFinal = LINQToDataTable(result); |
与
可以在字符串上联接,并将这两行放在匿名类型中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | var query = from r1 in dt1.AsEnumerable() join r2 in dt2.AsEnumerable() on r1.Field<string>("TEST2") equals string.Format("{0}-{1}-{2}" , r2.Field<string>("TEST2") , r2.Field<string>("TEST5") , r2.Field<string>("TEST6")) select new { r1, r2 }; foreach (var bothRows in query) { DataRow addedRow = dt.Rows.Add(); addedRow.SetField("TEST2", bothRows.r1.Field<string>("TEST2")); addedRow.SetField("TEST3", bothRows.r2.Field<string>("TEST3")); addedRow.SetField("TEST7", bothRows.r2.Field<string>("TEST7")); } |