[英]List<T> joins DataTable
我有一个对象列表(lst)和数据表(dt)。 我想在公共字段(代码为字符串)上加入 lst 和 dt,并且需要返回 lst 中的所有匹配行。
我的列表包含两列,即代码和名称以及以下值:
code name
==== ====
1 x
2 y
3 z
DataTable 包含两列,即代码和值以及以下值:
code value
==== =====
3 a
4 b
5 c
结果是:
3 z
下面是我的代码; 但我知道这不是一个正确的陈述,因此在这里寻求您的建议。 如果您能指导我如何写出正确的陈述,我将不胜感激。
var ld = from l in lst
join d in dt.AsEnumerable() on l.code equals d.code
select new { l.code, l.name };
您可以尝试以下任何一种。
var ld = from l in lst
join d in dt.AsEnumerable() on l.code equals d.Field<int>("code")
select new { l.code, l.name };
var ld = lst.Join(dt.AsEnumerable(), l => l.code, d => d.Field<int>("code"), (l,d) => new { l.code, l.name });
您可以使用 Linq 查询或 Join 扩展方法在代码上加入集合。 只是当您从数据表中选择数据时,您需要使用 dt.Field 方法。 请使用以下任一代码。
查询 1:
var ld = lst.Join(dt.AsEnumerable(),
l => l.code,
d => d.Field<string>("code"),
(l, d) => new
{
l.code,
l.name,
value = d.Field<string>("value")
}).ToList();
查询 2:
var ld = (from l in lst
join d in dt.AsEnumerable()
on l.code equals d.Field<string>("code")
select new
{
l.code,
l.name,
value = d.Field<string>("value")
}).ToList();
查询 3:
var ld = (from l in lst
join d in dt.AsEnumerable()
on l.code equals d.Field<string>("code")
let value = d.Field<string>("value")
select new
{
l.code,
l.name,
value
}).ToList();
目前尚不清楚您需要的输出是什么,但看起来您正确地获得了唯一的公共记录。 您可以将select
扩展到
select new { l.code, l.name, d.value }
这将提供两个表中的所有数据/列。
code name value
==== ==== =====
3 z a
尝试这个:
var ld = from l in lst
join d in dt.Cast <DataRow>() on l.code equals d["code"].ToString()
select new { l.code, l.name };
所以你有一个列表和一个数据表。 您不打算使用数据表的值,只使用代码。
您希望保留那些具有代码也是数据表中的代码的列表项。
如果您计划将 DataTable 用于其他用途,而不仅仅是为了解决这个问题,我的建议是首先创建一个过程将您的 DataTable 转换为可枚举序列。
这样你就可以添加 LINQ 语句,不仅针对这个问题,还针对其他问题。
让我们为您的 DataTable 创建一个扩展方法,将数据转换为 DataTable 中的项目。 请参阅揭秘扩展方法。
唉,我不知道你的 DataTable 中有什么,让我们假设你的 DataTable 包含Orders
class CustomerOrder
{
public int Id {get; set;}
public int CustomerId {get; set;}
public int Code {get; set;}
public string Value {get; set;}
...
}
扩展类 DataTable 功能的扩展方法:
public static IEnumerable<Order> ToCustomerOrders(this DataTable table)
{
return table.AsEnumerable().Select(row => new CustomerOrder
{
Id = ...
CustomerId = ...
Code = ...
Value = ...
};
}
我对 DataTables 不是很熟悉,但您知道如何将行的单元格转换为正确的值。
用法:
DataTable table = ...
Int customerId = 14;
var ordersOfThisCustomer = table.ToCustomerOrders
.Where(customerOrder => customerOrder.CustomerId == customerId)
.FirstOrDefault();
换句话说:将数据表逐行转换为 CustomerOrders,并检查每个转换后的 CustomerOrder 是否具有等于 14 的 CustomerId。如果找到则停止。 如果没有这样的行,则返回 null。
既然您已经有了一个很好的可重用程序,并且也易于测试、调试和更改,我们可以回答您的问题。
给定一个带有 CustomerOrders 的 DataTable,以及一个包含
Code
和Name
项目序列,只保留序列中那些 Code 也是 DataTable 中的 Code 的项目。
var dataTable = ... // your DataTable, filled with CustomerOrders.
var codeNames = ... // your list with Codes and Names
var codesInDataTable = dataTable.ToCustomerOrders
.Select(customerOrder => customerOrder.Code)
.Distinct();
这将创建一个可枚举序列,它将逐行转换您的 DataTable 并提取属性代码。 重复的代码值将被删除。
如果 Codes 是唯一的,则不需要 Distinct。
注意:可枚举序列还没有被枚举!
var result = codeNames
.Where(codeName => codesInDataTable.Contains(codeName.Code))
.ToList();
换句话说:对于列表中的每个 [Code, Name] 组合,只保留那些具有 Code 值的 [Code, Name] 组合也在codesInDataTable
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.