2016-11-03 15 views
3

私は典型的なTPTシナリオを持っています(なぜ私がTPTをやったのか尋ねないで、まずは愚かな選択だったと思います)、単純なCountを実行しようとしていますBASEタイプのクエリ。 ベースの種類とベースクラスのプロパティに基づいてカウントがあるため、私は理由を理解できませんが、EFはすべての派生型を一緒に結合してCOUNT(*)クエリを作成しています。Countテーブルタイプごとの継承でのクエリ生成

クラスは、このようなものです:

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 
} 

私のクエリは、このEFによって生成されたクエリは(第3クラス上に示したが、中には見ら​​れないがされている。この

SubmittedCasesCount = _context.Set<StudyCase>().Where(sc => !sc.Deleted).Count(sc => sc.DateSubmitted.HasValue); 

のようなものですクエリ):

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 a ND JOINそれがはるかに効率的(とのみ必要)になりながら、このような単純な数を行うには:

SELECT COUNT(1) AS [A1] 
FROM [dbo].[StudyCases] 
WHERE ([Deleted] <> 1) AND ([DateSubmitted] IS NOT NULL) 

派生クラスのプロパティが必要ない場合単純なクエリを生成するためにEFを強制的にどのように任意のアイデアやリターンセットが基本クラスのみのセットである場合(これは基本クラスのabstractキーワードにも依存しますが、EFは抽象クラスのプロキシを実現できるはずです)あなたは以下のように、基本クラスからプロパティのみを引っ張ってselect文を使用した場合に生成されるどのようなクエリ

+0

編集:、のようなものを、生のSQLクエリをやっているのを意識 –

答えて

2

SubmittedCasesCount = 
    _context 
     .Set<StudyCase>() 
     .Select(sc => new { Deleted = sc.Deleted, DateSubmitted = sc.DateSubmitted }) 
     .Where(anon => !anon.Deleted) 
     .Count(anon => anon.DateSubmitted.HasValue); 

編集: 悲しい上記と同じクエリ、私は唯一の他のソリューションを作り出します

int count = context.Set<StudyCase> 
        .FromSql("SELECT Deleted, DateSubmitted FROM dbo.StudyCases") 
        .Where(sc => !sc.Deleted).Count(sc => sc.DateSubmitted.HasValue) 
        .Count(); 
+0

をフォーマットするコードのための答えにこれを変更し悲しいことに、それは残念だ、まったく同じクエリ... – Tallmaris

+0

だ、私は別の方法で編集していますこれを達成するややエレガントなもの。 –

+0

カスタムクエリは、私には唯一の選択肢にも見えるが、私が行きたくなかった方向だった... – Tallmaris

関連する問題