合并两个实体

时间:2018-10-04 08:37:09

标签: c# entity-framework

我有一个使用EF Core的MVC项目。我已经创建了虚拟Dto以从数据库中选择逻辑查询。现在我被卡住了,我有一个方法

    public IEnumerable<FinalEntity> getTest(int month,int year)
    {
        var dataFromSpecialPayments = _sabresRepository.GetBrokerMonthlyCommissionSpecialPayments(month, year);
        var dataFromTotals = _sabresRepository.GetBrokerMonthlyCommissionTotals(month, year);

这两个变量包含逻辑和聚合之后的数据,并且它们的ID之间的关系为1:1(尽管在另一个表中有很多记录不匹配,因此需要成为一个完整的加入)。现在,我需要将这两个实体加入到我的最终实体中。这些是Dto的:

public class BrokerMonthlyCommission_Total_AggDto : DtoBase
{
    public int BrokerId { get; set; }
    public decimal TotalCommissionAmountBruto { get; set; }
    public decimal TotalCommissionAmountNeto { get; set; }
    public decimal TotalDistributingFeeParticipation { get; set; }
    public string BrokerName { get; set; }
    public int? CommissionPaymentStatusPl { get; set; }
    public int? MinCommissionForPayment { get; set; }
} 

public class BrokerMonthlyCommission_SpecialPayment_AggDto
{
    public int BrokerId { get; set; }
    public decimal TotalSpecialPayments { get; set; }
    public int PaymentStatus { get; set; }
}

public class FinalDto : DtoBase
{
    public int BrokerId { get; set; }
    public decimal TotalCommissionAmountBruto { get; set; }
    public decimal TotalCommissionAmountNeto { get; set; }
    public decimal TotalDistributingFeeParticipation { get; set; }
    public string BrokerName { get; set; }
    public int? CommissionPaymentStatusPl { get; set; }
    public int? MinCommissionForPayment { get; set; }
    public decimal TotalSpecialPayments { get; set; }
    public int PaymentStatus { get; set; }
} 

我该怎么做?我知道我可能可以使用foreach循环运行并遍历每条记录,但是我正在寻找更好的解决方案

3 个答案:

答案 0 :(得分:1)

使用Linq Join吗?

dataFromSpecialPayments.Join(dataFromTotals,
  sp => sp.Id,
  ft => ft.Id,
  (specialPayment, fromTotal) => new FinalDto 
  {
    BrokerId = specialPayment.BrokerId,
    /// etc
  })
  .ToList()

答案 1 :(得分:1)

此查询使用左联接和右联接的并集。 CommissionTotal的BrokerId为1、2和3。CommissionSpecial的BrokerId为1、2和4。结果是BrokerId分别为1、2、3和4。

void Main()
{
    var commissionTotal = new []
    {
        new BrokerMonthlyCommission_Total_AggDto { BrokerId = 1, TotalCommissionAmountBruto = 1000, TotalCommissionAmountNeto = 1000,
            TotalDistributingFeeParticipation = 1000, BrokerName = "B1", CommissionPaymentStatusPl = 1, MinCommissionForPayment = 2 },
        new BrokerMonthlyCommission_Total_AggDto { BrokerId = 2, TotalCommissionAmountBruto = 2000, TotalCommissionAmountNeto = 2000,
            TotalDistributingFeeParticipation = 2000, BrokerName = "B2", CommissionPaymentStatusPl = 1, MinCommissionForPayment = 2 },
        new BrokerMonthlyCommission_Total_AggDto { BrokerId = 3, TotalCommissionAmountBruto = 3000, TotalCommissionAmountNeto = 3000,
            TotalDistributingFeeParticipation = 2000, BrokerName = "B3", CommissionPaymentStatusPl = 1, MinCommissionForPayment = 2 }
    };

    var commissionSpecial = new []
    {
        new BrokerMonthlyCommission_SpecialPayment_AggDto { BrokerId = 1, TotalSpecialPayments = 100, PaymentStatus = 1 },
        new BrokerMonthlyCommission_SpecialPayment_AggDto { BrokerId = 2, TotalSpecialPayments = 300, PaymentStatus = 2 },
        new BrokerMonthlyCommission_SpecialPayment_AggDto { BrokerId = 4, TotalSpecialPayments = 900, PaymentStatus = 4 }
    };

    var leftJoin =
        from ct in commissionTotal
        join cs in commissionSpecial on ct.BrokerId equals cs.BrokerId into temp
        from cs in temp.DefaultIfEmpty(new BrokerMonthlyCommission_SpecialPayment_AggDto
        {
            BrokerId = ct.BrokerId,
            TotalSpecialPayments = default(decimal),
            PaymentStatus = default(int)
        })
        select new {CT = ct, CS = cs};

    var rightJoin =
        from cs in commissionSpecial
        join ct in commissionTotal on cs.BrokerId equals ct.BrokerId into temp
        from ct in temp.DefaultIfEmpty(new BrokerMonthlyCommission_Total_AggDto
        {
            BrokerId = cs.BrokerId,
            TotalCommissionAmountBruto = default(decimal),
            TotalCommissionAmountNeto = default(decimal),
            TotalDistributingFeeParticipation = default(decimal),
            BrokerName = default(string),
            CommissionPaymentStatusPl = default(int?),
            MinCommissionForPayment = default(int?)
        })
        select new {CT = ct, CS = cs};

    var final = leftJoin.Union(rightJoin).Select(x => new FinalDto
    {
        BrokerId = x.CT.BrokerId,
        TotalCommissionAmountBruto = x.CT.TotalCommissionAmountBruto,
        TotalCommissionAmountNeto = x.CT.TotalCommissionAmountNeto,
        TotalDistributingFeeParticipation = x.CT.TotalDistributingFeeParticipation,
        BrokerName = x.CT.BrokerName,
        CommissionPaymentStatusPl = x.CT.CommissionPaymentStatusPl,
        MinCommissionForPayment = x.CT.MinCommissionForPayment,
        TotalSpecialPayments = x.CS.TotalSpecialPayments,
        PaymentStatus = x.CS.PaymentStatus
    });
    final.Dump(); // remove this line if not in LinqPad
}

public class BrokerMonthlyCommission_Total_AggDto
{
    public int BrokerId { get; set; }
    public decimal TotalCommissionAmountBruto { get; set; }
    public decimal TotalCommissionAmountNeto { get; set; }
    public decimal TotalDistributingFeeParticipation { get; set; }
    public string BrokerName { get; set; }
    public int? CommissionPaymentStatusPl { get; set; }
    public int? MinCommissionForPayment { get; set; }
}

public class BrokerMonthlyCommission_SpecialPayment_AggDto
{
    public int BrokerId { get; set; }
    public decimal TotalSpecialPayments { get; set; }
    public int PaymentStatus { get; set; }
}

public class FinalDto
{
    public int BrokerId { get; set; }
    public decimal TotalCommissionAmountBruto { get; set; }
    public decimal TotalCommissionAmountNeto { get; set; }
    public decimal TotalDistributingFeeParticipation { get; set; }
    public string BrokerName { get; set; }
    public int? CommissionPaymentStatusPl { get; set; }
    public int? MinCommissionForPayment { get; set; }
    public decimal TotalSpecialPayments { get; set; }
    public int PaymentStatus { get; set; }
}

LinqPad中的结果: enter image description here

注意:

  1. 由于没有该类,因此我从DtoBase中删除了继承。
  2. BrokerName对于BrokerId = 4而言为null,因为它是来自BrokerMonthlyCommission_SpecialPayment_AggDto的右连接,并且没有BrokerName属性。

答案 2 :(得分:0)

您基本上可以使用System.Linq库中的select来实现此目的,并将类型手动转换为FinalDto。

var dataFromSpecialPayments = _sabresRepository.GetBrokerMonthlyCommissionSpecialPayments(month, year)
    .Select(x => new FinalDto
    {
        BrokerId = x.BrokerId,
        //assign other properties
    });