EF查询确实产生了大量查询

时间:2018-03-12 07:56:42

标签: entity-framework entity-framework-core

我有以下数据模型:

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 个答案:

答案 0 :(得分:0)

使用includes

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

这将使用INNER JOIN创建一个查询,但作为子选择。但仍有一个问题。

现在,如果你真的需要一个伪对象,你仍然可以创建一个伪对象,但它不应该是IMO。

修改:添加了sample project,证明这不会导致两次查询。

这就是创建的查询

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]