【问题标题】:How to do a double left outer join in Linq query syntax(or fluent)如何在 Linq 查询语法(或流利)中进行双左外连接
【发布时间】:2017-01-22 08:48:13
【问题描述】:
var Claim   = new[] {   new { ClaimId = 10, Desc = "item 10" },
    new { ClaimId = 11, Desc = "item 11" },
    new { ClaimId = 12, Desc = "item 12" },
    new { ClaimId = 13, Desc = "item 13" }};
var Insured = new[] {   new { ClaimId = 10, IsPolicyHolder = true, IsInsured = true, Forename = "10A Pol TRUE Ins TRUE NoSiblings" },
    new { ClaimId = 11, IsPolicyHolder = true, IsInsured = false, Forename = "11A Pol TRUE Ins false NoSiblings" },
    new { ClaimId = 12, IsPolicyHolder = false, IsInsured = true, Forename = "12A Pol false Ins TRUE NoSiblings" },
    new { ClaimId = 13, IsPolicyHolder = true, IsInsured = false, Forename = "13A Pol TRUE Ins false has sibling" },
    new { ClaimId = 13, IsPolicyHolder = false, IsInsured = true, Forename = "13B Pol false Ins TRUE has sibling" }};

    Insured.Dump("Insured Table");

var leftJoinTry =
    from in1 in Insured where in1.IsPolicyHolder == true
    join p in Insured on in1.ClaimId equals p.ClaimId into ps 
    //where ps.IsInsured == true   ****ERROR****
    from p in ps.DefaultIfEmpty()
    select new { in1.ClaimId, in1.IsPolicyHolder, in1.IsInsured, in1.Forename, p_Forename = p.Forename};
leftJoinTry.Dump("leftJoinTry");    

var initialResults = from c in Claim
join pa in Insured on c.ClaimId equals pa.ClaimId where pa.IsPolicyHolder == true
join pb in Insured on pa.ClaimId equals pb.ClaimId where pb.IsInsured == true
select new { c.ClaimId, pa_Forename = pa.Forename, pb_Forename = pb.Forename, };

initialResults.Dump("initialResults");

var query =
    from in1 in Insured where in1.IsPolicyHolder == true
    join p in Insured on in1.ClaimId equals p.ClaimId into ps 
    //where ps.IsInsured == true
    from p in ps.DefaultIfEmpty()
    select new { Category = in1, ProductName = p /*== null ? "(No products)" : p.Forename*/ };
query.Dump("query");

上面的 Linq pad 给出了以下结果集

请注意,使用的数据库的主键为 ClaimId(int) 和 IsPolicyHolder(bool),并且存在 IsPolicyHolder 或 IsInsured 字段必须为 True 的约束。

我真正想要的是 IsPolicyHolder 和 IsInsured 为 True 的所有记录,其中有一个 IsPolicyHolder 为 True 且 IsInsured 为 False 且与 IsPolicyHolder 相同的 ClaimId 为 False 且 IsInsured 为 True 记录合并为 ClaimId 13 下。请注意,任何没有其他 ClaimId 同级的记录,其中一个 IsPolicyHolder 和 IsInsured 设置为 False,另一个设置为 True,也必须包括在内,并将未知的 Forename(下面的斜体)设置为已知的 Forename(下面的粗体)。

【问题讨论】:

    标签: c# linq join left-join outer-join


    【解决方案1】:
    var firstDate = new DateTime(2016,1,1);
    var secondDate = new DateTime(2016,9,1);
    var company = "Some_Co.";
    var resultCombined = from c in Claims
    join cc in ClaimCovers
    on c.ClaimId equals cc.ClaimId
    join cov in Covers
    on cc.CoverId equals cov.CoverId
    join pa in Insureds.Where(x => x.IsPolicyHolder == true) on c.ClaimId equals pa.ClaimId 
           into pas from pa in pas.DefaultIfEmpty() 
    join pb in Insureds.Where(x => x.IsInsured == true) on c.ClaimId equals pb.ClaimId
           into pbs from pb in pbs.DefaultIfEmpty()
           join ci in ClaimIncidents
                                  on c.ClaimId equals ci.ClaimId
                                  where c.DateReported >= firstDate && c.DateReported <= secondDate
                                     where c.CompanyID == company
    select new { c.ClaimId, PolicyRefernce = c.PolicyReference ?? "",
                                      c.ClaimReference,
                                      c.DateOfLoss,
                                      c.DateReported,
                                      cov.CoverCode,
                                      cov.Description, c.Status,
                                      ci.NotifiedBy,
                                      ci.HowNotified,
                                      ci.ClaimTypeCode,
                                      ci.CauseCode,
                                      ci.AtFault, 
                                      //pa is the first list where policyHolder = true
                                      PolicyHolderName = pa.Forename + " " + pa.Surname, pa_Postcode = pa.Postcode, 
                                      //pb is the second list where insured = true
                                      InsuredName = pb.Forename + " " + pb.Surname, pb_Postcode = pb.Postcode,};    
    
    resultCombined.Dump();
    

    不匹配的记录给出可以设置为空字符串等的空值......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-25
      • 2013-05-26
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      相关资源
      最近更新 更多