我在小型.NET 4.5,MVC4,EF5项目上使用Repository Pattern。
我注意到如果我改变从存储库传递的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?
答案 0 :(得分:1)
这是存储库反模式,最好删除该“存储库”。如果您确实想使用Repository,请定义一个与EF无关的接口,并且没有方法返回IQueryable。此外,存储库的使用与否与EF生成sql的方式无关。