![](/img/trans.png)
[英]Compare Row of 1st Datatable with Column of 2nd Datatable and build 3rd datatable with matched columns
[英]C# - Copy rows from one DataTable by comparing with 2nd DataTable to 3rd DataTable
我的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
。 還需要將不匹配的記錄存儲在第四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;
我不喜歡在不需要時使用var。 您正在失去對實際操作的跟蹤。 mathcingRows是一個列表。 因此任務很簡單:
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);
}
您可以創建兩個查詢來查找匹配和不匹配的行,然后將這些行復制到每個答案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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.