0

小さな .NET 4.5、MVC4、EF5 プロジェクトでリポジトリ パターンを使用しています。

リポジトリから渡された IQueryable オブジェクトの結果を変更すると、生成された SQL が望ましくないことに気付きました。

たとえば、私のリポジトリでは:

    public IQueryable<Entry> GetEntries()
    {
        // (db is an instance of the data context)
        return db.Entries.Where(e => e.UserId == WebSecurity.CurrentUserId);
    }

私のコントローラーでは、返される行の量を制限して並べ替えます。

    public ActionResult Index()
    {
        // (repo is an instance of the repository object)
        var entries = repo.GetEntries().Take(10).OrderByDescending(o => o.Created)
        return View(entries);
    }

これにより、次の SQL が生成されます。

DECLARE @p__linq__0 int = 1

SELECT 
[Project1].[UserId] AS [UserId], 
[Project1].[Id] AS [Id], 
[Project1].[Created] AS [Created], 
[Project1].[LastModified] AS [LastModified], 
[Project1].[BodyOriginal] AS [BodyOriginal], 
[Project1].[BodyFormatted] AS [BodyFormatted], 
[Project1].[FormatterVersion] AS [FormatterVersion], 
[Project1].[BodyDigest] AS [BodyDigest], 
[Project1].[FollowupId] AS [FollowupId], 
[Project1].[AddMethod] AS [AddMethod], 
[Project1].[Entry_Id] AS [Entry_Id]
FROM ( SELECT 
        [Extent1].[Id] AS [Id], 
        [Extent1].[UserId] AS [UserId], 
        [Extent1].[Created] AS [Created], 
        [Extent1].[LastModified] AS [LastModified], 
        [Extent1].[BodyOriginal] AS [BodyOriginal], 
        [Extent1].[BodyFormatted] AS [BodyFormatted], 
        [Extent1].[FormatterVersion] AS [FormatterVersion], 
        [Extent1].[BodyDigest] AS [BodyDigest], 
        [Extent1].[FollowupId] AS [FollowupId], 
        [Extent1].[AddMethod] AS [AddMethod], 
        [Extent1].[Entry_Id] AS [Entry_Id]
        FROM [dbo].[Entries] AS [Extent1]
        WHERE [Extent1].[UserId] = @p__linq__0
)  AS [Project1]
ORDER BY [Project1].[Created] DESC  

ご覧のとおり、生成された SQL は非常に冗長です。

切り捨てられ、並べ替えられた結果を含めるようにリポジトリ メソッドを変更すると、次のようになります。

    public IQueryable<Entry> GetEntries()
    {
        // (db is an instance of the data context)
        return db.Entries.Where(e => e.UserId == WebSecurity.CurrentUserId).Take(10).OrderByDescending(o => o.Created);
    }

生成された SQL の方が優れています。

DECLARE @p__linq__0 int = 1

SELECT 
            [Extent1].[Id] AS [Id], 
            [Extent1].[UserId] AS [UserId], 
            [Extent1].[Created] AS [Created], 
            [Extent1].[LastModified] AS [LastModified], 
            [Extent1].[BodyOriginal] AS [BodyOriginal], 
            [Extent1].[BodyFormatted] AS [BodyFormatted], 
            [Extent1].[FormatterVersion] AS [FormatterVersion], 
            [Extent1].[BodyDigest] AS [BodyDigest], 
            [Extent1].[FollowupId] AS [FollowupId], 
            [Extent1].[AddMethod] AS [AddMethod], 
            [Extent1].[Entry_Id] AS [Entry_Id]
            FROM [dbo].[Entries] AS [Extent1]
            WHERE [Extent1].[UserId] = @p__linq__0
  ORDER BY [Extent1].[Created] DESC  

この問題を解決するにはどうすればよいですか。つまり、リポジトリ パターンを利用しながら、不完全に構築された SQL を作成せずにリポジトリの結果を変更する柔軟性を維持するにはどうすればよいですか?

4

1 に答える 1