使用行方式减法将两个表合并为一个表

时间:2014-10-20 19:49:03

标签: c# linq join group-by

请帮我设置以下条件的linq:

TBL1:

ID | Total
1     20.00
2     90.00
3    130.00

TBL2:

ID | Total
1     10.00
2     30.00

差异表:(tbl1-tbl2)

ID | Total
1     10.00
2     60.00
3    130.00

请让我知道如何构建这个。

2 个答案:

答案 0 :(得分:2)

在SQL世界中,您将tbl1和union all tbl2与负总数相加,然后group byid与值相加

var query = from x in tbl1.Concat(tbl2.Select(t => new { ID = t.ID, Total = -t.Total }))
            group x by x.ID into x
            select new
            {
              ID = x.Key,
              Total = x.Sum(y => y.Total)
            };

答案 1 :(得分:0)

这基本上是一个完整的外连接,可以表示为左外连接和右外连接的并集。

class DataModel
{
    public int ID { get; set; }
    public decimal Total { get; set; }

    public override string ToString() { return string.Format("{0}:{1}", ID, Total); }
    public override int GetHashCode() { return ID; }
    public override bool Equals(object other)
    {
        DataModel otherModel = other as DataModel;
        if (otherModel == null) return false;
        return ID == otherModel.ID;
    }
}

IEnumerable<DataModel> table1 = new List<DataModel> {
    new DataModel { ID = 1, Total = 20m },
    new DataModel { ID = 2, Total = 90m },
    new DataModel { ID = 3, Total = 130m }
};
IEnumerable<DataModel> table2 = new List<DataModel> {
    new DataModel { ID = 1, Total = 10m },
    new DataModel { ID = 2, Total = 30m },
    new DataModel { ID = 4, Total = 15m }
};

IEnumerable<DataModel> leftOuterJoin = from one in table1
    join two in table2 on one.ID equals two.ID into temp
    from right in temp.DefaultIfEmpty()
    select new DataModel {
        ID = one.ID,
        Total = one.Total - (right == null ? 0m : right.Total)
    };
IEnumerable<DataModel> rightOuterJoin = from two in table2
    join one in table1 on two.ID equals one.ID into temp
    from left in temp.DefaultIfEmpty()
    select new DataModel {
        ID = two.ID,
        Total = (left == null ? 0m : left.Total) - two.Total
    };

IEnumerable<DataModel> difference = leftOuterJoin.Union(rightOuterJoin);
foreach (DataModel item in difference)
{
    Console.WriteLine(item);
}

控制台输出是:

1:10
2:60
3:130
4:-15

See the fiddle