比较具有几个键的两个数据表,并选择第二个表中不存在的行

时间:2018-08-20 04:41:33

标签: c# linq datatable

我有两个DataTables,我想从第一个中选择不存在于第二个中的行,两个表都有3个键custnum,shiptonum,connum

例如:

表格联系人

custnum  shiptonum  connum  column
   1        1         1     data1    
   2        2         2     data2
   3        3         3     data3
   4        4         4     data4

餐桌邀请函

custnum  shiptonum  connum  column
   1        1         1     data11
   3        3         3     data33

我希望结果是:

表格结果

custnum  shiptonum  connum  column
   2        2         2     data2
   4        4         4     data4 

我已经尝试使用

变量差异= table1.AsEnumerable()。Except(table2.AsEnumerable(),DataRowComparer.Default);

但是没有用。例如,在我在“联系人”表中的测试中,我有14389条记录,在“邀请”表中,我在联系人表中有两条记录,使用上述解决方案后的计数是14389,而不是14387(从“邀请”表中删除了两条记录)。

2 个答案:

答案 0 :(得分:0)

您写道:

  

我想从第一行中选择第二行中不存在的行

从您的示例中,我看到您不想从第一张表中选择不是第二张表中的行的行,而只想考虑键的值:

  

我要从tableA中选择所有行,这些行的键值不是tableB的键

您没有定义表格。它们可能是IQueryableIEnumerable,对于您的LINQ语句并没有太大的区别。尽量避免使用AsEnumerable,尤其是在您的数据源处于不同过程(例如数据库管理系统)的情况下。另一个过程比执行过程更有效地执行查询。 AsEnumerable将所有数据从另一个进程传输到您的进程,这是一个相对缓慢的过程。因此,通常是:仅在确实需要时使用AsEnumerable

第二个定义更清晰地定义了您想要的内容:显然,从tableB您只需要按键:

var keysTableB = tableB.Select(row => new
    {
         CustNum = row.custNum,
         ShipToNum = row.shiptonum,
         ConNum = row.connum,
    });

换句话说:在tableB的每一行中,创建一个具有三个属性的匿名类型的新对象:CustNumShipToNumConNum

Select使用延迟执行。不执行查询,仅更改属性Expression

现在,您只想保留tableA中具有作为序列keysTableB成员的键的行:如果要保留序列的子集,请使用Where

var result = tableA.Where(row => keysTableB.Contains(new
    {
         CustNum = row.custNum,
         ShipToNum = row.shiptonum,
         Connum = row.connum,
    }));

换句话说:使用值相等性,在tableB的每一行中仅保留具有也在keysTableB中的键的那些行。

TODO:考虑将这两个LINQ语句合并为一个。
我怀疑这是否会提高性能。它肯定会降低代码的可读性,从而降低更改性/维护性/可测试性。

答案 1 :(得分:0)

"proxy": {
  "/auth/google": {
    "target": "http://127.0.0.1:5000"
  }
}