繁体   English   中英

存储库模式和IQueryable <>生成错误的SQL

[英]Repository pattern and IQueryable<> generating bad SQL

我在一个小型.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?

这是存储库反模式,最好删除该“存储库”。 如果您确实要使用存储库,请定义一个与EF无关的接口,并且没有方法返回IQueryable。 此外,是否使用存储库与EF如何生成sql无关。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM