我正在使用sql profiler来查看Ef core2.1生成的sql, 这是我的linq查询:
var resulat = (from a in A
join b in B equals a.level=b.level
where ...
select new M1 {AId = a.id}).Distinct();
(from r in resulat
join c in C equals r.AId = c.AId
select new M2
{
CId = c.Id,
level = _helper(c.level)
}).Distinct();
生成的SQL:
select t.AId,c.Id,c.level
from
(
select distinct a.id
from A a
inner join B b on a.level=b.level
where ...
) as t
inner join C c on t.AId = c.AId
我想要的结果是:
select distinct c.Id,c.level
from
(
select distinct a.id
from A a
inner join B b on a.level=b.level
where ...
) as t
inner join C c on t.AId = c.AId
我也尝试过对结果IQueryable使用select / distinct,但是生成的sql是相同的。 我在linq查询中错过了什么,或者我必须添加什么才能拥有此sql查询
答案 0 :(得分:1)
这对我有用:
这是我纠正后的查询:
var resulat = from a in A
join b in B equals a.level=b.level
where ...
select new M1 {AId = a.id};
(from r in resulat
join c in C equals r.AId = c.AId
select new M2
{
CId = c.Id
level = c.level
}).Distinct();
非常感谢您的评论,它确实对我有所帮助。
答案 1 :(得分:1)
我一直很乐意直接从返回数据的表(当然,DbSet)中查询所需的数据。该过程看起来类似于以下步骤:
C.Id
和C.Level
context.Cs
。C
个?A
的父级,其中至少一个B
与A
具有相同的“级别”,并且满足其他两个条件({{1} })。等于:
where ...
如果from c in context.Cs
where context.Bs.Any(b => b.level == c.A.level && <other criteria>)
select new { c.Id, c.Level }
还包含where ...
的过滤条件,则可以将A
之类的谓词添加到&& c.A == ...
。
请注意,我假设存在导航属性where
,否则将要创建导航属性,因为c.A
具有C
。