如何在 Linq 查询语法(或流利的)中进行双左外连接
How to do a double left outer join in Linq query syntax(or fluent)
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并且相同的ClaimId与IsPolicyHolder为False和IsInsured为True的记录合并如下面的 ClaimId 13。请注意,任何没有其他 ClaimId 兄弟姐妹的记录,其 IsPolicyHolder 和 IsInsured 之一设置为 False,另一个设置为 True 也必须包括在内,并将未知的 Forename(下面的斜体)设置为已知的 Forename(下面的粗体)。
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();
不匹配的记录给出可以设置为空字符串等的空值...
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并且相同的ClaimId与IsPolicyHolder为False和IsInsured为True的记录合并如下面的 ClaimId 13。请注意,任何没有其他 ClaimId 兄弟姐妹的记录,其 IsPolicyHolder 和 IsInsured 之一设置为 False,另一个设置为 True 也必须包括在内,并将未知的 Forename(下面的斜体)设置为已知的 Forename(下面的粗体)。
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();
不匹配的记录给出可以设置为空字符串等的空值...