我对LINQ中的连接有疑问。我目前正在将访问应用程序转换为.NET,其中从两个不同服务器上的两个不同数据库中检索数据。在旧应用程序中,可以通过一个查询检索数据:
SELECT *,tbl2.Descr,tbl2.Form FROM tbl2 RIGHT JOIN tbl1 ON tbl2.proId2 = tbl1.proId
我发现在.NET中执行此操作的一种方法是单独检索两个表,然后使用LINQ连接它们。我没有LINQ的经验所以我的逻辑或代码可能完全错了,因为我似乎无法使它工作。
首先我尝试进行普通连接(没有权利)但是当两个表包含近2000行时,只返回18行。我还检查了数据,它应该肯定会导致更多行,没有那么多空单元格。所以然后我把右/左连接放在一起,但实际上这会导致错误。当我调试它时,一切都很好,当执行LINQ语句但是当我进入foreach时,会显示错误,并且在linq语句中实际指示错误,表示table2为空。当我检查table1时,我也只看到22个数据库。
我做错了什么?
DataTable dtTarget= data1.Clone();
var dt2Columns = data2.Columns.OfType<DataColumn>().Select(dc =>
new DataColumn(dc.ColumnName, dc.DataType, dc.Expression, dc.ColumnMapping));
var dt2FinalColumns = from dc in dt2Columns.AsEnumerable()
where dtTarget.Columns.Contains(dc.ColumnName) == false
select dc;
dtTarget.Columns.AddRange(dt2FinalColumns.ToArray());
var results = from table1 in data1.AsEnumerable()
join table2 in data2.AsEnumerable()
on table1.Field<String>("proId") equals table2.Field<String>("proId2")
select table1.ItemArray.Concat(table2.ItemArray).ToArray();
foreach (object[] values in results)
dtTarget.Rows.Add(values);
外部加入:
var results = from table1 in data1.AsEnumerable()
join table2 in data2.AsEnumerable() on table1.Field<String>("proId") equals table2.Field<String>("proId2") into t_join
from table2 in t_join.DefaultIfEmpty(null) select table1.ItemArray.Concat(table2.ItemArray).ToArray();
答案 0 :(得分:0)
我注意到你正在使用字符串作为连接键。也许字符串比较在环境(访问与.net)之间是不同的。 Access可能使用不区分大小写的比较,而.net的默认值区分大小写。
要使.net使用不区分大小写的比较,这是第一个查询:
var results = data1.AsEnumerable()
.Join(
data2.AsEnumerable(),
row1 => row1.Field<String>("proId"),
row2 => row2.Field<String>("proId2"),
(row1, row2) => row1.ItemArray.Concat(row2.ItemArray).ToArray(),
StringComparer.InvariantCultureIgnoreCase); //and now caps are ignored.
和第二个查询:
var results = data1.AsEnumerable()
.GroupJoin(
data2.AsEnumerable(),
row1 => row1.Field<String>("proId"),
row2 => row2.Field<String>("proId2"),
(row1, row2s) => new {Row1 = row1, Row2s = row2s},
StringComparer.InvariantCultureIgnoreCase)
.SelectMany(
x => x.row2s.DefaultIfEmpty(null)),
(x, row2) => row2 == null ? x.Row1.ItemArray : x.Row1.ItemArray.Concat(row2.ItemArray).ToArray()
);