如何用linq减去两个数据表

时间:2012-08-27 05:45:56

标签: c# linq datatable

有没有办法减去两个数据表,以便第一个数据表的行不在第二个数据表中?

我尝试过类似下面的.Except()方法,但它对我不起作用。

dt1.AsEnumerable().Except(dt2.AsEnumerable()).CopyToDataTable();

我认为我使用这种方法有误,但我找不到?

4 个答案:

答案 0 :(得分:3)

您可以使用IEquailtyComparer

创建自己的Comparer
 public class CustomDataRowComparer : IEqualityComparer<DataRow>
    {
        public bool Equals(DataRow x, DataRow y)
        {
            for (int i = 0; i < x.Table.Columns.Count; i++)
            {
                if (x[i].ToString() != y[i].ToString())
                {
                    return false;
                }

            }
            return true;
        }

        public int GetHashCode(DataRow obj)
        {
            return obj.ToString().GetHashCode();
        }
    }

稍后您可以将其称为:

CustomDataRowComparer myDRComparer = new CustomDataRowComparer();
var result2 = dt1.AsEnumerable().Except(dt2.AsEnumerable(),myDRComparer).CopyToDataTable();

答案 1 :(得分:1)

Except无效,因为引用不同。内存中数据行的每个“副本”都是不同的对象,因此在Except中进行的相等比较将始终返回false。

您需要与可比较的内容进行比较,例如行ID。几个想法如何做到这一点:

var rowsInFirstNotInSecond = dt1.Rows.Where(r1=>!dt2.Rows.Any(r2=>r1.ID == r2.ID)); 

或者:

var rowsInFirstNotInSecond = dt1.Rows.Where(r1=>dt2.FindById(r1.ID) == null);

答案 2 :(得分:1)

我使用以下代码相互减去两个数据表:

var query =    
    from row1 in dt1    
    where !(from row2 in dt2    
            select row2.ID)    
           .Contains(row1.ID)    
    select row1;

此代码完全返回我想要的内容......

答案 3 :(得分:1)

本守则有效:

var rows =dtFirst.AsEnumerable().Except(dtSecond.AsEnumerable(), DataRowComparer.Default);
 DataTable result = null;
 if (rows.Count() != 0)
      result = rows.CopyToDataTable();