C# 在数据表中查找不匹配的值
C# Find non matching values in DataTables
我正在努力解决以下问题:
有 2 个数据表(在我的例子中是 SSFE 和 FE)。
FE 将包含与 SSFE 匹配的项目,但它也将包含 SSFE 中不存在的值。
例如
SSFE 1,2,3,4,5,6,9,10
FE 1,2,3,4,5,6,7,8,9,10,11
本例中我需要的输出是:7、8、11。
我正在使用以下代码查找匹配项:
DataSet set = new DataSet();
//wrap the tables in a DataSet.
set.Tables.Add(SSFEData);
set.Tables.Add(FEData);
//Creates a ForeignKey like Join between two tables.
//Table1 will be the parent. Table2 will be the child.
DataRelation relation = new DataRelation("IdJoin", SSFEData.Columns[0], FEData.Columns[0], false);
//Have the DataSet perform the join.
set.Relations.Add(relation);
//Loop through table1 without using LINQ.
for (int i = 0; i < SSFEData.Rows.Count; i++)
{
//If any rows in Table2 have the same Id as the current row in Table1
if (SSFEData.Rows[i].GetChildRows(relation).Length > 0)
{
SSFEData.Rows[i]["PackageError"] = SSFEData.Rows[i].GetChildRows(relation)[0][1];
SSFEData.Rows[i]["SaleError"] = SSFEData.Rows[i].GetChildRows(relation)[0][2];
}
}
应该有一个技巧来找到这些没有关系的项目。
任何建议都会很棒!
嗯,您当然可以通过使用 AsEnumerable()
1 扩展方法将数据表转换为 IEnumerables
来使用一点 LINQ。
我使用一些假设来说明这一点:
- "id" 是具有与
FEData
和 SSFEData
中的行相关的整数值的列。
- "id" 是
FEData
和 SSFEData
上的主键列。
然后这将 return FEData
中不存在于 SSFEData
中的行的列表:
var notInSSFEData = FEData.AsEnumerable()
.Where(x => SSFEData.Rows.Find((object)x.Field<int>("id")) == null)
.ToList();
如果上面的假设 2 不成立(即 "id" 字段不是主键),则需要稍微复杂一些的查询。
var notInSSFEData = FEData.AsEnumerable()
.Where(x1 => !SSFEData.AsEnumerable().Any(x2 => x2.Field<int>("id") == x1.Field<int>("id")))
.ToList();
1 这需要添加对 System.Data.DataSetExtensions
的引用(在 System.Data.DataSetExtensions.dll 中)。
我正在努力解决以下问题:
有 2 个数据表(在我的例子中是 SSFE 和 FE)。 FE 将包含与 SSFE 匹配的项目,但它也将包含 SSFE 中不存在的值。
例如
SSFE 1,2,3,4,5,6,9,10
FE 1,2,3,4,5,6,7,8,9,10,11
本例中我需要的输出是:7、8、11。
我正在使用以下代码查找匹配项:
DataSet set = new DataSet();
//wrap the tables in a DataSet.
set.Tables.Add(SSFEData);
set.Tables.Add(FEData);
//Creates a ForeignKey like Join between two tables.
//Table1 will be the parent. Table2 will be the child.
DataRelation relation = new DataRelation("IdJoin", SSFEData.Columns[0], FEData.Columns[0], false);
//Have the DataSet perform the join.
set.Relations.Add(relation);
//Loop through table1 without using LINQ.
for (int i = 0; i < SSFEData.Rows.Count; i++)
{
//If any rows in Table2 have the same Id as the current row in Table1
if (SSFEData.Rows[i].GetChildRows(relation).Length > 0)
{
SSFEData.Rows[i]["PackageError"] = SSFEData.Rows[i].GetChildRows(relation)[0][1];
SSFEData.Rows[i]["SaleError"] = SSFEData.Rows[i].GetChildRows(relation)[0][2];
}
}
应该有一个技巧来找到这些没有关系的项目。
任何建议都会很棒!
嗯,您当然可以通过使用 AsEnumerable()
1 扩展方法将数据表转换为 IEnumerables
来使用一点 LINQ。
我使用一些假设来说明这一点:
- "id" 是具有与
FEData
和SSFEData
中的行相关的整数值的列。 - "id" 是
FEData
和SSFEData
上的主键列。
然后这将 return FEData
中不存在于 SSFEData
中的行的列表:
var notInSSFEData = FEData.AsEnumerable()
.Where(x => SSFEData.Rows.Find((object)x.Field<int>("id")) == null)
.ToList();
如果上面的假设 2 不成立(即 "id" 字段不是主键),则需要稍微复杂一些的查询。
var notInSSFEData = FEData.AsEnumerable()
.Where(x1 => !SSFEData.AsEnumerable().Any(x2 => x2.Field<int>("id") == x1.Field<int>("id")))
.ToList();
1 这需要添加对 System.Data.DataSetExtensions
的引用(在 System.Data.DataSetExtensions.dll 中)。