C# 具有相同字段的两个表之间的LINQ并集,然后在集合中返回

C# 具有相同字段的两个表之间的LINQ并集,然后在集合中返回,c#,sql,sql-server,linq,devforce,C#,Sql,Sql Server,Linq,Devforce,我已经放弃尝试创建linq查询来检索sql server视图,该视图是两个表之间的联合。我现在将尝试创建一个linq联盟 我有两种观点,MemberDuesPaid和MemberDuesOwed。他们在这两个领域都有相同的领域;(批次号、交易日期、借方金额、贷方金额、收款号、支票号、SocSecNo) 我的应用程序中还有一个名为MemberTransaction的助手类。它具有所有相同的属性 如何在socSecNo=传入的ssn的两个表之间进行联合?我想合并这两个表并返回MemberTransa

我已经放弃尝试创建linq查询来检索sql server视图,该视图是两个表之间的联合。我现在将尝试创建一个linq联盟

我有两种观点,MemberDuesPaid和MemberDuesOwed。他们在这两个领域都有相同的领域;(批次号、交易日期、借方金额、贷方金额、收款号、支票号、SocSecNo)

我的应用程序中还有一个名为MemberTransaction的助手类。它具有所有相同的属性


如何在socSecNo=传入的ssn的两个表之间进行联合?我想合并这两个表并返回MemberTransaction的IEnumerable集合。将两个表联合在一起后,我希望将trandate返回的集合按降序排序。

假设您有两个集合,每个集合代表一个视图:

var paid = new List<MemberDuesPaid>();

var owed = new List<MemberDuesOwed>();
现在您已经有了一个
MemberTransaction
的集合,但是没有任何东西可以指示一个
MemberTransaction
如何等于另一个。因此,如果您只运行上面的操作,那么最终将得到结果中两个集合的所有内容,而不是真正的联合

您必须通过在
MemberTransaction
类上实现
IEquatable
来告诉它是什么使两个实例相等

public class MemberTransaction : IEquatable<MemberTransaction>
{
    public int BatchNo { get; set; }
    public DateTime TranDate { get; set; }
    public decimal DebitAmount { get; set; }
    public decimal CreditAmount { get; set; }
    public int ReceiptNo { get; set; }
    public int CheckNo { get; set; }
    public int SocSecNo { get; set; }

    public bool Equals(MemberTransaction other)
    {
        return BatchNo == other.BatchNo
               && TranDate.Equals(other.TranDate)
               && DebitAmount == other.DebitAmount
               && CreditAmount == other.CreditAmount
               && ReceiptNo == other.ReceiptNo
               && CheckNo == other.CheckNo
               && SocSecNo == other.SocSecNo;
    }
}
公共类MemberTransaction:IEquatable
{
public int BatchNo{get;set;}
公共日期时间转换日期{get;set;}
公共十进制DebitAmount{get;set;}
公共十进制贷记金额{get;set;}
public int ReceiptNo{get;set;}
public int CheckNo{get;set;}
public int SocSecNo{get;set;}
公共布尔等于(其他成员事务)
{
返回BatchNo==other.BatchNo
&&TranDate.Equals(其他.TranDate)
&&DebitAmount==其他。DebitAmount
&&CreditAmount==其他。CreditAmount
&&ReceiptNo==其他。ReceiptNo
&&CheckNo==其他。CheckNo
&&SocSecNo==其他。SocSecNo;
}
}

您可以在Linq Union查询中执行此操作:

var infoQuery =
    (from paid in db.MemberDuesPaid 
    select new MemberTransaction() {
        BatchNo = paid.BatchNo,
        TranDate = paid.TranDate,
        DebitAmount = paid.DebitAmount,
        CreditAmount = paid.CreditAmount,
        ReceiptNo = paid.ReceiptNo,
        CheckNo = paid.CheckNo,
        SocSecNo = paid.SocSecNo})
    .Union
        (from owed in db.MemberDuesOwed
        select new MemberTransaction() {
        BatchNo = owed.BatchNo,
        TranDate = owed.TranDate,
        DebitAmount = owed.DebitAmount,
        CreditAmount = owed.CreditAmount,
        ReceiptNo = owed.ReceiptNo,
        CheckNo = owed.CheckNo,
        SocSecNo = owed.SocSecNo});
这将返回一个集合,将所有内容合并到一个列表中

[编辑]

如果需要不同的值,可以在上面的语句之后执行类似的操作(如果将所有内容都括起来,则可以内联执行,但这更易于解释):


此时变量
infoQuery
将完全由
MemberTransaction
类型的对象填充,而不是union语句中的两种不同类型的对象。

像这样吗?这看起来确实有点过于复杂了。使用Linq:)可以在不修改现有类的情况下获得结果。是的,它将返回所有行,但在这种情况下,数据源是独立的,因此我假设OP希望这样做。:)(我本来打算建议添加
Distinct()
,但我没有测试它)。当我测试它时,我只返回了不同的记录。哦,我应该说我将整个查询(即,联合的两部分)括起来,然后运行
Distinct()
。这样,您将苹果与相同类型的
MembershipTransaction
进行比较。
Union
已经删除了重复的值。这是一个基于集合的操作,因此它返回一个集合作为结果。集合不包含重复的值。在后面添加
Distinct
是多余的。
var infoQuery =
    (from paid in db.MemberDuesPaid 
    select new MemberTransaction() {
        BatchNo = paid.BatchNo,
        TranDate = paid.TranDate,
        DebitAmount = paid.DebitAmount,
        CreditAmount = paid.CreditAmount,
        ReceiptNo = paid.ReceiptNo,
        CheckNo = paid.CheckNo,
        SocSecNo = paid.SocSecNo})
    .Union
        (from owed in db.MemberDuesOwed
        select new MemberTransaction() {
        BatchNo = owed.BatchNo,
        TranDate = owed.TranDate,
        DebitAmount = owed.DebitAmount,
        CreditAmount = owed.CreditAmount,
        ReceiptNo = owed.ReceiptNo,
        CheckNo = owed.CheckNo,
        SocSecNo = owed.SocSecNo});
infoQuery = infoQuery.Distinct();