首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >计数每类型表继承中的查询生成

问计数每类型表继承中的查询生成
EN

Stack Overflow用户
提问于 2016-11-03 23:57:25
回答 1查看 95关注 0票数 3

我有一个典型的TPT场景(不要问我为什么要做TPT,一开始这可能是一个愚蠢的选择),我正尝试在基类型上运行一个简单的计数查询。考虑到计数是基于基类型和基类上的属性的,我不明白为什么EF通过将所有派生类型连接在一起来创建COUNT(*)查询。

这些类如下所示:

代码语言:javascript
复制
public abstract class StudyCase {
    public DateTime? DateSubmitted { get; protected set; }
    public bool Deleted { get; set; }
}

public class StudyCaseStandard : StudyCase { 
// ... other stuff
}

public class StudyCaseReview : StudyCase { 
// ... other stuff
}

我的查询是这样的

代码语言:javascript
复制
SubmittedCasesCount = _context.Set<StudyCase>().Where(sc => !sc.Deleted).Count(sc => sc.DateSubmitted.HasValue);

这是EF生成的查询(上面没有显示,但在查询中可以看到第三个类):

代码语言:javascript
复制
SELECT 
    [GroupBy1].[A1] AS [C1]
    FROM ( SELECT 
        COUNT(1) AS [A1]
        FROM   (SELECT 
            [Extent1].[Id] AS [Id]
            FROM [dbo].[StudyCases_Exacerbation] AS [Extent1]
        UNION ALL
            SELECT 
            [Extent2].[Id] AS [Id]
            FROM [dbo].[StudyCases_Standard] AS [Extent2]
        UNION ALL
            SELECT 
            [Extent3].[Id] AS [Id]
            FROM [dbo].[StudyCases_Review] AS [Extent3]) AS [UnionAll2]
        INNER JOIN [dbo].[StudyCases] AS [Extent4] ON [UnionAll2].[Id] = [Extent4].[Id]
        WHERE ([Extent4].[Deleted] <> 1) AND ([Extent4].[DateSubmitted] IS NOT NULL)
    )  AS [GroupBy1]
go

正如你所看到的,它正在做所有的UNION和JOIN,而像这样做一个简单的计数会更有效率(也是唯一必要的):

代码语言:javascript
复制
SELECT COUNT(1) AS [A1]
FROM [dbo].[StudyCases]
WHERE ([Deleted] <> 1) AND ([DateSubmitted] IS NOT NULL)

当不需要派生类的属性时,或者当返回集只是基类的集合时(这也可能取决于基类上的abstract关键字,但EF应该能够实现抽象类的代理),你知道如何强制EF生成更简单的查询吗?

EN

回答 1

Stack Overflow用户

发布于 2016-11-04 01:55:44

如果使用select语句仅从基类中提取属性,则会生成什么查询,如下所示:

代码语言:javascript
复制
SubmittedCasesCount = 
    _context
        .Set<StudyCase>()
        .Select(sc => new { Deleted = sc.Deleted, DateSubmitted = sc.DateSubmitted })
        .Where(anon => !anon.Deleted)
        .Count(anon => anon.DateSubmitted.HasValue);

编辑:不幸的是,上面产生了相同的查询,我所知道的唯一其他解决方案是执行一个原始的SQL查询,类似于:

代码语言:javascript
复制
int count = context.Set<StudyCase>
                   .FromSql("SELECT Deleted, DateSubmitted FROM dbo.StudyCases")
                   .Where(sc => !sc.Deleted).Count(sc => sc.DateSubmitted.HasValue)
                   .Count();
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40406080

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档