简体   繁体   English

如何用linq减去两个数据表

[英]how to subtract two datatables with linq

Is there any way to subtract two datatables in order to have rows of the first datatable that are not in the second one? 有什么方法可以减去两个数据表,以使第一个数据表的行不在第二个数据表中?

I have tried .Except() method like below but it does not work for me. 我已经尝试过.Except()方法,如下所示,但它对我不起作用。

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

I think i have mistake in using this method but i could not find that? 我认为我在使用此方法时有错误,但是我找不到?

You can create your own Comparer using IEquailtyComparer 您可以使用IEquailtyComparer创建自己的比较器

 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();
        }
    }

Later you can call it like: 以后您可以这样称呼它:

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

Except will not work because the references are different. 因为引用不同,所以Except将不起作用。 Each "copy" of a data row in memory is a different object, thus the equality comparison being made in Except will always return false. 内存中数据行的每个“副本”都是一个不同的对象,因此在“ Except中进行的相等比较将始终返回false。

You need to compare with something comparable, like row IDs. 您需要与类似的东西进行比较,例如行ID。 A couple ideas how to do this: 几个想法如何做到这一点:

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

Or: 要么:

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

I have used the following code to subtract two datatables from each other : 我使用以下代码相互减去两个数据表:

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

this code returns exactly what i want... 此代码完全返回我想要的...

This Code works for sure: 该代码可以肯定地起作用:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM