ASP.NET C# LINQ左连接两个DataTable结果异常问题求助
解决LINQ左连接DataTable时Stock列为空的问题
我一眼就看出问题出在你拼接列的逻辑上——你的左连接语法本身是对的,但你错误地把右表的整行数据拼接到了左表行后面,导致结果列的映射完全错位了。
问题分析
你的代码里用了rowLeft.ItemArray.Concat(subRight.ItemArray),这会把左表的[ID, name]和右表的[ID, stock]拼接成一个4元素的数组[ID, name, ID, stock]。但你的结果表dtblResult只有3列(ID, name, stock),当你调用Rows.Add(values)时,只会取数组的前3个元素填充到结果表中——也就是左表ID、左表name、右表ID,而真正需要的stock值是第4个元素,根本没被放进结果表的stock列里,这就是为什么你看到stock列全是空的。
修正后的代码
你需要只拼接右表中你需要的stock列,而不是整个行的所有列。这里有两种更可靠的写法:
写法1:精准选择需要的列(推荐,避免列顺序问题)
var rowDataLeftOuter = from rowLeft in dtblLeft.AsEnumerable() join rowRight in dtblRight.AsEnumerable() on rowLeft[colToJoinOn] equals rowRight[strTempColName] into gj from subRight in gj.DefaultIfEmpty() select new object[] { rowLeft["ID"], rowLeft["name"], // 左连接无匹配时用DBNull.Value填充,避免空引用 subRight != null ? subRight["stock"] : DBNull.Value }; foreach (object[] values in rowDataLeftOuter) dtblResult.Rows.Add(values);
写法2:基于原ItemArray拼接指定列
如果你的左表列比较多,不想逐个写列名,可以在左表ItemArray后面只追加stock列:
var rowDataLeftOuter = from rowLeft in dtblLeft.AsEnumerable() join rowRight in dtblRight.AsEnumerable() on rowLeft[colToJoinOn] equals rowRight[strTempColName] into gj from subRight in gj.DefaultIfEmpty() select rowLeft.ItemArray .Concat(new object[] { subRight?["stock"] ?? DBNull.Value }) .ToArray(); foreach (object[] values in rowDataLeftOuter) dtblResult.Rows.Add(values);
额外注意事项
- 确保
colToJoinOn和strTempColName对应的列值类型完全一致(比如都是int),否则join条件会匹配失败,导致stock列全为空。 - 结果表
dtblResult的列结构必须和你拼接后的数组长度、类型对应:3列,依次是ID、name、stock,类型分别匹配左表ID、左表name、右表stock的类型。
这样修改后,你就能得到预期的左连接结果了:
| ID | name | stock |
|---|---|---|
| 1 | item1 | blabla |
| 1 | item2 | blabla |
| 3 | item3 | bla2 |
内容的提问来源于stack exchange,提问作者Adriano
相关产品推荐
相关产品推荐

