DataTable dt1 = new DataTable();
DataTable dt2 = new DataTable();
dt1.Columns.Add("id");
dt2.Columns.Add("id");
dt1.Columns.Add("val1");
dt2.Columns.Add("val1");
dt1.Columns.Add("val2");
dt1.Columns.Add("val2");
dt1.Rows.Add(new string[] { "1", "a", "a1" });
dt1.Rows.Add(new string[] { "2", "b", "b1" });
dt1.Rows.Add(new string[] { "", "b", "b1" });
dt1.Rows.Add(new string[] { "4", "", "c1" });
dt2.Rows.Add(new string[] { "1", "a", "a1" });
dt2.Rows.Add(new string[] { "2", "b", "b1" });
dt2.Rows.Add(new string[] { "3", "c", "c1" });
dt2.Rows.Add(new string[] { "3", "c", "c1" });
dt2.Rows.Add(new string[] { "4", "d", "d1" });
dt2.Rows.Add(new string[] { "5", "e", "e1" });
结果应仅包含dt1中不存在的值。我们可以用linq
来做到这一点答案 0 :(得分:1)
是的,您可以使用LINQ执行此操作,我会这样做:
var dataRows1 = st1.AsEnumerable().Select(r => new {
Id = r["id"], Val1 = r["val1"], Val2 = r["val2"] });
var dataRows2 = st2.AsEnumerable().Select(r => new {
Id = r["id"], Val1 = r["val1"], Val2 = r["val2"] });
这为您提供了IEnumerable<T>
个可以与之比较的匿名类型。然后,你可以这样做:
var dt2NotInDt1 = dataRows2.Where(r2 => !dataRows1.Any(r1 => r1.Equals(r2));
请注意,这假设您的比较条件是行中的所有值(包括id
)。
另请注意拨打Equals
的电话。匿名类型覆盖Equals
方法,以提供匿名类型的所有属性的值比较。来自"Anonymous Types" section of the C# Programming Guide:
因为匿名类型上的
Equals
和GetHashCode
方法是 根据{{1}}和Equals
方法定义 属性,同一匿名类型的两个实例仅在相等时才相等 他们所有的财产都是平等的。
您可以根据约束条件简化此逻辑。例如,如果存在主键(或某种唯一行标识符),则可以将行放在键入该值的字典中,然后根据该值执行查找。
在您的情况下,假设GetHashcode
是唯一的,您可以这样做(在顶部的前两行之后):
id
这将为您提供一个地图,然后您可以对其进行查找(我正在切换到查询语法,因为我相信它在这里更具可读性。)
var dataRows1Map = dataRows1.ToDictionary(r => r.Id);