LiNQ比较两个数据表

时间:2015-11-04 17:31:35

标签: c# linq csv datatable

之前已经问过这个问题,但这个具体部分还没有。 我有两个csv文件,1.csv和2.csv。

我首先将它们都转换为DataTable 它们都具有相同的模式:

1.csv
ID SUBID QTY Value
a  1     55  TEN
a  2     5   FIFTH
b  1     2   TE

我需要将上表与下表中映射的主键{ID,SUBID}与容差为1位数的QTY进行比较:

2.csv
ID SUBID QTY Value
a  1     5  TEN
a  2     6  FIFTH
b  1     2  TEN

输出应该只是2.csv值的差异数据和输出

output.csv
ID SUBID QTY Value
a  1     5  
b  1        TEN

当然,这可以通过阅读1.csv中的所有值并使用{ID,SUBID} - >字典来完成。 {QTY,Value}并以这种方式匹配,但这是一个巨大的列表,时间复杂性将是巨大的。 我想知道是否有办法通过LiNQ执行此操作,即获取1.csv {ID,SUBID}与2.csv {ID,SUBID}匹配并遍历数据表,如果{QTY - 容差超过1的任何不匹配#OR str(Value)差异}把它放在一个新的数据表中。

1 个答案:

答案 0 :(得分:2)

我会使用FileHelpers将您的csv加载到自定义类中,然后您可以执行此操作:

var inner=csv1.Join(csv2,
    c1=>new {c1.ID,c1.SUBID},
    c2=>new {c2.ID,c2.SUBID},
    (c1,c2)=>new {c1,c2}).Where(c=>c.c1.Value!=c.c2.Value || Math.Abs(c1.QTY-c2.QTY)>1)
  .Select(c=>new {
    c2.ID,
    c2.SUBID,
    QTY=(c.c1.QTY==c.c2.Value)?null,c.c2.Value,
    Value=c.c1.Value==c.c2.Value?null,c.c2.Value);

使用MoreLinq,您可以这样做:

var left=csv1.ExceptBy(csv2,c=>new {c.ID,c.SUBID})
  .Select(c=>new {c.ID,c.SUBID,QTY=null,Value=null});
var right=csv2.ExceptBy(csv1,c=>new {c.ID,c.SUBID});

var combined=inner.Concat(left).Concat(right);

然后使用FileHelper将合并后的结果写回CSV。

如果您知道csv1中ID,SUBID的所有组合都在csv2中,并且csv2中的所有组合也在csv1中,那么您不需要左/右,只能输出内在的是什么。