我的C#代码中有4个DataTables
;
DataTable dt1;
DataTable dt2;
DataTable dt3;
DataTable dt4;
dt1
有以下记录
Id | Name | City
----------------
1 | Abc | Khi
2 | XYZ | Hyd
3 | TVW | Lhr
4 | tyz | Isb
dt2
只有ID记录
Id
---
2
4
我只需要复制dt1
中dt2
到dt3
中可用的行。还需要在第4 dt4
我发现了这一点,但不知道如何正确地复制到datatable
以及not equals
如何在这里工作
var matchingRows = from s1 in dt1.AsEnumerable()
join s2 in d2.AsEnumerable() on s1.Field<int>("Id") equals s2.Field<int>("Id")
select s1;
答案 0 :(得分:2)
我不喜欢在没有必要时使用var。你正在忽视你实际在做什么。 mathcingRows是一个List。所以任务很简单:
List<DataRow> matchingRows = (from s1 in dt1.AsEnumerable()
join s2 in dt2.AsEnumerable() on s1.Field<int>("Id") equals s2.Field<int>("Id")
select s1).ToList();
foreach (DataRow row in matchingRows)
{
dt4.Rows.Add(row);
}
答案 1 :(得分:2)
您可以创建两个查询来查找匹配和不匹配的行,然后将行复制到每个答案DataTable
中:
var dt3 = dt1.Clone();
var dt4 = dt1.Clone();
var matchingRows = from s1 in dt1.AsEnumerable()
join s2 in dt2.AsEnumerable() on s1.Field<int>("Id") equals s2.Field<int>("Id")
select s1;
matchingRows.CopyToDataTable(dt3, LoadOption.OverwriteChanges);
var nonMatchingRows = from s1 in dt1.AsEnumerable()
where !dt2.AsEnumerable().Any(s2 => s2.Field<int>("Id") == s1.Field<int>("Id"))
select s1;
nonMatchingRows.CopyToDataTable(dt4, LoadOption.OverwriteChanges);
如果dt2
包含大量条目且性能比内存更重要,则可以将dt2
转换为HashSet
以优化匹配测试:
var dt2hs = new HashSet<int>(dt2.AsEnumerable().Select(r => r.Field<int>("Id")));
var matchingRows = from s1 in dt1.AsEnumerable()
where dt2hs.Contains(s1.Field<int>("Id"))
select s1;
var nonMatchingRows = from s1 in dt1.AsEnumerable()
where !dt2hs.Contains(s1.Field<int>("Id"))
select s1;
另一个性能选项是只扫描dt1
一次,然后手动循环并选择每个目的地:
var dt1jdt2 = from s1 in dt1.AsEnumerable()
join s2 in dt2.AsEnumerable() on s1.Field<int>("Id") equals s2.Field<int>("Id") into s2j
from s2 in s2j.DefaultIfEmpty()
select new { s1, s2 };
foreach (var r in dt1jdt2) {
if (r.s2 != null)
dt3.Rows.Add(r.s1.ItemArray);
else
dt4.Rows.Add(r.s1.ItemArray);
}
当然,您可以将HashSet
和单次扫描选项结合使用:
var dt2hs = new HashSet<int>(dt2.AsEnumerable().Select(r => r.Field<int>("Id")));
foreach (var s1 in dt1.AsEnumerable())
if (dt2hs.Contains(s1.Field<int>("Id")))
dt3.Rows.Add(s1.ItemArray);
else
dt4.Rows.Add(s1.ItemArray);