我有以下LinQ
查询:
List<string> emails = (from u in context.User
join h in context.Hero
on u.UserID equals h.UserID
join hc in context.HeroCategory
on h.HeroID equals hc.HeroID
where
(hc.QuestionCategoryID == 1
&& h.IsHeroAdmin) || h.IsHeroSuperAdmin
select u.EmailAddress).ToList<string>();
如果英雄属于某个类别且他是管理员或英雄是超级管理员,我正在尝试获取电子邮件列表。
当我尝试使用左连接在sql
中编写上述查询时,我得到了正确的结果:
SELECT
U.EmailAddress
FROM USERS U LEFT JOIN
Heroes H ON (U.UserID=H.UserID) LEFT JOIN
HeroCategory HC ON (H.HeroID=HC.HeroID)
WHERE (HC.QuestionCategoryID=1 AND H.IsHeroAdmin=1)
OR H.IsHeroSuperAdmin=1
基本上我想知道在上面提到的linq查询中执行简单的左连接。
答案 0 :(得分:1)
像这样的东西,但你应该在where子句中处理空值,因为如果你正在做left join
那么为什么要过滤而不考虑空值?:
List<string> emails = (from u in context.User
join h in context.Hero on u.UserID equals h.UserID into hleft
from hl in hleft.DefaultIfEmpty()
join hc in context.HeroCategory on hl.HeroID equals hc.HeroID into hcleft
from hcl in hcleft.DefaultIfEmpty()
where
(hcl.QuestionCategoryID == 1
&& hl.IsHeroAdmin) || hl.IsHeroSuperAdmin
select u.EmailAddress).ToList<string>();
答案 1 :(得分:0)
因为您在WHERE
条款中测试了英雄的价值观,所以您已经有效地将英雄的LEFT JOIN
变为INNER JOIN
。唯一LEFT JOIN
需要的是HeroCategory
上的HeroCategory
,然后只有当Hero不是超级拉丁时(再次,因为你测试QuestionCategoryId
&#39; s {的价值{1}}如果他们不是SuperAdmin
)。
你需要首先修复你的逻辑,但这里是等价的,假设Users to Heros是一对多的关系,HeroCategories
是一对多:
var emails=context.Users
.Where(u=>u.Heros.Any(h=>
(h.IsHeroAdmin==1 && h.HeroCategories.Any(hc=>hc.QuestionCategoryID==1))
|| u.Heros.Any(h=>h.IsHeroSuperAdmin==1)))
.Select(u=>u.EmailAddress)
.ToList();
如果用户与Heros是1:1的关系,那么它将是这样的:
var emails=context.Users
.Where(u=>(u.Heros.IsHeroAdmin==1 && h.Heros.HeroCategories.Any(hc=>hc.QuestionCategoryID==1)) || u.Heros.IsHeroSuperAdmin==1)
.Select(u=>u.EmailAddress)
.ToList();