【问题标题】:EntityFramework Core SubqueryEntityFramework 核心子查询
【发布时间】:2020-02-12 18:44:51
【问题描述】:

我是 Entity Framework Core 的新手,不知道如何翻译下面的 SQL 查询以使用 EF。以下是我的查询:

SELECT *
FROM Project
WHERE Project_Id IN(

    SELECT Project_Id
    FROM IP
    GROUP BY Project_Id
    HAVING COUNT(Project_Id)<= 2
)

我尝试了下面的脚本,但返回了项目表中的所有记录。

var projs = _context.Project
    .FromSqlRaw("SELECT * FROM Project WHERE Project_Id IN(SELECT Project_Id FROM IP GROUP BY Project_Id HAVING COUNT(Project_Id)<= 2)")
    .ToList();

感谢任何帮助!

【问题讨论】:

  • 旁注:如果您在跨表查询时使用 EXISTS 或 JOIN 而不是 IN,通常会获得更高性能的查询计划。

标签: c# sql .net entity-framework


【解决方案1】:

你可以试试这个方法

var groupByCount = _context.IP.GroupBy(p => p.Project_Id)
                              .Select(g => new { Project_Id = g.Key, Count = g.Count() })
                              .ToList();
var Project_Ids = groupByCount.Where(p => p.Count <= 2).Select(p => p.Project_Id)
                               .ToArray(); 

var projs  = (from p in _context.Project
             where Project_Ids.Contains(p.Project_Id)
             select p).ToList(); 

【讨论】:

  • 感谢示例代码,但我收到以下错误:...无法翻译。以可翻译的形式重写查询,或通过插入对 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync() 的调用显式切换到客户端评估。
  • 你调试了吗?groupByCount 结果是什么样的?
  • 请像这样添加.ToList()var projs = _context.Project.Where(p =&gt; groupByCount.Any(g =&gt; g.Project_Id == p.Project_Id &amp;&amp; g.Count &lt;= 2)).ToList();
  • 我尝试了修改后的代码,但收到了同样的错误。我将 groupByCount 转储到一个列表中: [ { "project_Id": 1, "count": "3" }, { "project_Id": 2, "count": "2" }, { "project_Id": 22, "count ": "1" } ]
  • 我刚刚更新了我的答案,请看@Terry Doll
【解决方案2】:

如果我猜对了你的 ER 模型,这应该可以工作:

_context.Project.Where(proj=> proj.IP.Count <= 2);

【讨论】:

  • 感谢代码 sn-p,但 IP 是另一个数据库上下文而不是字段。
  • 在接受的答案中,它使用相同的上下文 (_context),因此它们必须在相同的上下文中,并且通过您的 sql,两个表都在同一个数据库中。为什么不在 db 中的 project_id 上添加外键,无论如何它都应该有它,有了这个 FK,你可以使用 IP(或 IP)作为导航属性,我的代码行就可以了。这是 EF 的超能力之一,您无需编写复杂的查询。
猜你喜欢
  • 1970-01-01
  • 2012-06-15
  • 1970-01-01
  • 1970-01-01
  • 2013-08-05
  • 1970-01-01
  • 2017-10-18
  • 2021-12-02
  • 1970-01-01
相关资源
最近更新 更多