You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用主键通过LINQ连接DataTable返回空表,求正确实现方案

问题描述

尝试通过主键(两张表的ID列均为主键)连接clientDT和orderDT,但查询结果为空表。以下是表结构、数据、期望结果及当前代码,请修正查询以得到正确结果。

表结构与数据

clientDT

IDnamecity
1JohnNew York
2JacobLos Angeles
3WilliamChicago
4EthanSan Francisco

orderDT

IDorder_number
1123547
2568688
389779

期望结果表

nameorder_numbercity
John123547New York
Jacob568688Los Angeles
William89779Chicago

当前代码

var result = from client in clientDT.AsEnumerable()
             join orders in orderDT.AsEnumerable()
                  on clientDT.PrimaryKey equals orderDT.PrimaryKey
             select new 
                    {
                        Name = client.Field<string>("name"),
                        City = client.Field<string>("city"),
                        Order_number = orders.Field<string>("order_number")                      
                       
                    };
            DataTable dt = new DataTable();
            dt.Columns.Add("name", typeof(string));
            dt.Columns.Add("city", typeof(string));
            dt.Columns.Add("order_number", typeof(string));
            foreach(var row in result)
            {
                dt.Rows.Add(new object[] { row.Name, row.City, row.Order_number});
            }
            
result_DT  = dt;

问题原因与修正方案

错误出在连接条件:你用了clientDT.PrimaryKey和orderDT.PrimaryKey,这两个是表的主键定义对象(DataColumn数组),并非当前行的主键值,自然无法匹配到任何数据。

基础修正代码(直接指定主键列名)

直接取每行的ID列值进行匹配,这是最直观的写法:

var result = from client in clientDT.AsEnumerable()
             join orders in orderDT.AsEnumerable()
                  on client.Field<int>("ID") equals orders.Field<int>("ID")
             select new 
                    {
                        Name = client.Field<string>("name"),
                        City = client.Field<string>("city"),
                        Order_number = orders.Field<string>("order_number")                      
                    };
            DataTable dt = new DataTable();
            dt.Columns.Add("name", typeof(string));
            dt.Columns.Add("city", typeof(string));
            dt.Columns.Add("order_number", typeof(string));
            foreach(var row in result)
            {
                dt.Rows.Add(new object[] { row.Name, row.City, row.Order_number});
            }
            
result_DT  = dt;

动态主键匹配(无需硬编码列名)

如果想通过表的主键定义动态获取值,避免硬编码列名,可以这样写:

// 假设两张表都是单主键,取第一个主键列
var clientPkCol = clientDT.PrimaryKey[0];
var orderPkCol = orderDT.PrimaryKey[0];

var result = from client in clientDT.AsEnumerable()
             join orders in orderDT.AsEnumerable()
                  on client[clientPkCol] equals orders[orderPkCol]
             select new 
                    {
                        Name = client.Field<string>("name"),
                        City = client.Field<string>("city"),
                        Order_number = orders.Field<string>("order_number")                      
                    };
// 后续创建DataTable的代码不变

额外优化建议

  • 若order_number实际存储的是整数类型,建议改用Field<int>("order_number"),避免不必要的字符串类型转换。
  • 如果需要保留无订单的客户(比如示例中的Ethan),可改用左连接:
var result = from client in clientDT.AsEnumerable()
             join orders in orderDT.AsEnumerable()
                  on client.Field<int>("ID") equals orders.Field<int>("ID") into orderGroup
             from order in orderGroup.DefaultIfEmpty()
             select new 
                    {
                        Name = client.Field<string>("name"),
                        City = client.Field<string>("city"),
                        Order_number = order?.Field<string>("order_number") ?? string.Empty
                    };

内容的提问来源于stack exchange,提问作者sereganator

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 19:58:32