使用连接时,我似乎无法超越 Linq 的 select 子句使用的匿名类型。我想将查询结果放入数据表中。这是我在运行时内存中的内容...
DataTable1 (source)
----------
col1A <int> (acting PK, not explicitly defined as such)
col1B <string>
col1C <string>
col1D <string> (FK -> dt2.col2A, also not explicitly defined)
col1E <string>
DataTable2 (source)
----------
col2A <string> (acting PK, also not explicitly defined)
col2B <string>
DataTable3 (destination)
----------
colA <int>
colB <string>
colC <string>
colD <string>
这就是我想要的(SQL 等价于我正在寻找的)......
INSERT INTO DataTable3 (colA, colB, colC, colD)
SELECT dt1.col1A, dt1.col1B, dt1.col1C, dt2.col2B
FROM DataTable1 dt1
LEFT JOIN DataTable2 dt2 ON (dt1.col1D = dt2.col2A)
向后工作,我看到这条简单的线将枚举查询结果集放入数据表中:
DataTable DataTable3 = query.CopyToDataTable();
这是我尝试过的...我不知道如何以允许我使用它的方式构建“查询”。尝试 1(使用 var 查询;这有效,请进一步阅读):
var query =
from dt1 in DataTable1.AsEnumerable()
join dt2 in DataTable2.AsEnumerable()
on dt1.Field<string>("col1D") equals dt2.Field<string>("col2A")
select new { col1A = dt1.Field<int>("col1A"),
col1B = dt1.Field<string>("col1B"),
col1C = dt1.Field<string>("col1C"),
col2B = dt2.Field<string>("col2B") };
但这给了我在“query.CopyToDataTable()”上的这个错误:
“错误 1 类型 'AnonymousType#1' 不能用作泛型类型或方法 'System.Data.DataTableExtensions.CopyToDataTable(System.Collections.Generic.IEnumerable)' 中的类型参数 'T'。没有隐式引用转换从 'AnonymousType#1' 到 'System.Data.DataRow'。”
据我推测,此错误是因为“选择新”不会将 DataRows 构建到 .CopyToDataTable() 要求的“查询”中;它只是建立匿名记录。此外,我不知道如何将查询元素转换为 DataRow,因为“由于保护级别,它无法访问”。
尝试 2(使用 IEnumerable 查询;不要费心尝试这个):
IEnumerable<DataRow> query =
from dt1 in DataTable1.AsEnumerable()
join dt2 in DataTable2.AsEnumerable()
on dt1.Field<string>("col1D") equals dt2.Field<string>("col2A")
select new { col1A = dt1.Field<int>("col1A"),
col1B = dt1.Field<string>("col1B"),
col1C = dt1.Field<string>("col1C"),
col2B = dt2.Field<string>("col2B") };
这会在“加入”时出现错误:
“错误 5 无法将类型 'System.Collections.Generic.IEnumerable' 隐式转换为 'System.Collections.Generic.IEnumerable'。存在显式转换(您是否缺少演员表?)”
附带说明一下,如果我注释掉 'join' 子句(以及 'select' 中相应的 dt2 列),我会在 'select' 上收到此错误:
“错误 2 无法将类型 'System.Data.EnumerableRowCollection' 隐式转换为 'System.Collections.Generic.IEnumerable'。存在显式转换(您是否缺少演员表?)”
我还尝试使用列预先定义 DataTable3,以给“select”子句一个真正的 DataRow 来关闭,但我仍然无法让“select”利用它。
编辑、详细信息、解决方案:感谢 Tim 的帮助。我选择了尝试 1(var 查询)。我还这样预定义了 DataTable3:
DataTable DataTable3 = new DataTable();
DataTable3.Columns.Add("colA", System.Type.GetType("System.Int32"));
DataTable3.Columns.Add("colB", System.Type.GetType("System.String"));
DataTable3.Columns.Add("colC", System.Type.GetType("System.String"));
DataTable3.Columns.Add("colD", System.Type.GetType("System.String"));
正如蒂姆建议的那样,我使用 foreach 循环存储了“查询”的结果:
foreach (var x in query)
{
DataRow newRow = DataTable3.NewRow();
newRow.SetField("colA", x.col1A);
newRow.SetField("colB", x.col1B);
newRow.SetField("colC", x.col1C);
newRow.SetField("colD", x.col2B);
DataTable3.Rows.Add(newRow);
}
这可以通过一些额外的努力以几种方式通用化,但这对于我的目的来说已经足够了。