当前位置: 首页 > 知识库问答 >
问题:

EF查询确实会生成大量查询[重复]

逄宁
2023-03-14

我有以下数据模型:

AuthorizationObject [1 : n] Scopes

我想执行以下选择:

    var result = await _context.AuthorizationObject
        .Select(x => new
        {
            x.RoleId,
            x.DefinitionId,
            Scopes = x.Scopes.Select(s => s.Name).ToList()
        })
        .ToListAsync();

因为我必须考虑性能,所以我想在一个选择中执行它,比如(伪):

select a.RoleId a.DefinitionId s.Name from AuthorizationObject As a
inner join Scope As s ...

不幸的是,它执行了这样的操作:

SELECT [x].[RoleId], [x].[DefinitionId], [x].[Id]
FROM [AuthorizationObject] AS [x]

SELECT [s].[ScopeDefinitionId]
FROM [Scope] AS [s]
WHERE @_outer_Id = [s].[AuthorizationObjectId]

SELECT [s].[ScopeDefinitionId]
FROM [Scope] AS [s]
WHERE @_outer_Id = [s].[AuthorizationObjectId]

SELECT [s].[ScopeDefinitionId]
FROM [Scope] AS [s]
WHERE @_outer_Id = [s].[AuthorizationObjectId]

SELECT [s].[ScopeDefinitionId]
FROM [Scope] AS [s]
WHERE @_outer_Id = [s].[AuthorizationObjectId]

SELECT [s].[ScopeDefinitionId]
FROM [Scope] AS [s]
WHERE @_outer_Id = [s].[AuthorizationObjectId]

...

更新:SamiAl90建议的解决方案:此查询

    var result = await _context.AuthorizationObject
        .Include(x => x.Scopes)
        .ToListAsync();

产生以下sql:

SELECT [x].[Id], [x].[DefinitionId], [x].[Metadata], [x].[RoleId]
FROM [AuthorizationObject] AS [x]
ORDER BY [x].[Id]

SELECT [x.Scopes].[AuthorizationObjectId], [x.Scopes].[ScopeDefinitionId], [x.Scopes].[ValueString]
FROM [Scope] AS [x.Scopes]
INNER JOIN (
    SELECT [x0].[Id]
    FROM [AuthorizationObject] AS [x0]
) AS [t] ON [x.Scopes].[AuthorizationObjectId] = [t].[Id]
ORDER BY [t].[Id]

共有1个答案

简意
2023-03-14

使用包括。

var result = await context.Set<AuthorizationObject>()
   .AsQueryable()
   .Include(a => a.Scopes)
   .ToListAsync();

这将创建一个具有内部连接但作为子选择的查询。不过还有一个问题。

现在,如果你真的需要一个伪对象,你仍然可以创建一个,但在我看来,这是不必要的。

编辑:添加了一个示例项目,证明这不会导致两个查询。

这就是创建的查询

SELECT [p.Children].[Id], [p.Children].[ParentId]
FROM [ChildClass] AS [p.Children]
INNER JOIN (
    SELECT [p0].[Id]
    FROM [ParentClass] AS [p0]
) AS [t] ON [p.Children].[ParentId] = [t].[Id]
ORDER BY [t].[Id]
 类似资料:
  • 我不确定这是否是一个错误,但我遇到了一些主要的性能问题。EF Core正在为一个简单的语句生成多个查询。 这是查询: 预期结果: 然而,EF正在生成: UPDATE用EF core 2.1.0-preview2-Final测试过还是一样的问题

  • 我有一个复合密钥的实体。订阅和源具有多对多的关系。 我正在使用Spring数据存储库来处理它。 当我尝试使用方法saveAll时,它会抛出 “com.mysql.jdbc.exceptions.jdbc4.mysqlsyntaxerrorexception:未知列'subscripti0_.subscription_id'” 同时尝试在保存后返回值。 Hibernate生成以下查询: 所以,现在我

  • 我有表,当我添加新行时,我想计算一个id号。 条件: 如果我有缺失的数字,请给出最小的一个(3),如果我没有缺失的数字,请给出一行中的下一个数字(5) 如何将此条件构建到查询中? 我的查询: 桌子 如果我缺少id,则解决方案 如果我没有丢失的id,则解决方案

  • 我想不出如何使用TypeOrm查询生成器编写以下MySql语句 从farm.reg中选择reg.id,其中grpId=“abc”; 这个选择返回的只是ID的,但我的查询生成器返回的是整个对象。 现在,我在我的NestJs服务中有这个函数,但我需要使用'map',我不想… 谢谢

  • 有几种不同方法可以生成查询结果: 结果数组 结果行 自定义结果对象 结果辅助方法 Class Reference 结果数组 result() 方法 该方法以**对象数组**形式返回查询结果,如果查询失败返回**空数组**。 一般情况下,你会像下面这样在一个 foreach 循环中使用它: $query = $this->db->query("YOUR QUERY"); foreach ($que

  • 我试图从一个表中选择所有结果,并在用户ID匹配时与另一个表合并。 我有三个表:runs、users和一个run\u用户透视表。我想从数据透视表中的“运行”和其他列(即“已完成”、“粘性”、“上次测试”和“难度”)中选择所有结果,但只从当前用户的“运行用户”中提取数据。 在原始SQL中,我通过一个带有AND语句的左连接成功地做到了这一点: 如何通过查询生成器执行此操作,有何建议?我可以在Larave