EF核心2.1选择/不同

时间:2019-01-06 12:25:45

标签: c# sql-server linq c#-6.0 ef-core-2.1

我正在使用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查询

2 个答案:

答案 0 :(得分:1)

这对我有用:

  1. 结果查询中删除 Distinct(),这样可以避免在我的选择中添加 t.AId
  2. 从我的选择字段之一中删除一个辅助方法,执行将Distinct()添加到最终查询中。

这是我纠正后的查询:

    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)中查询所需的数据。该过程看起来类似于以下步骤:

  1. 我想要C.IdC.Level
  2. 那是context.Cs
  3. 我想要哪个 C个?
  4. 具有父级A的父级,其中至少一个BA具有相同的“级别”,并且满足其他两个条件({{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