我仍然对存储库模式有些困惑.我想要使用此模式的主要原因是避免从域调用EF 4.1特定数据访问操作.我宁愿从IRepository接口调用泛型CRUD操作.这将使测试更容易,如果我将来必须更改数据访问框架,我将能够这样做,而无需重构大量代码.
这是我的情况的一个例子:
我在数据库中有3个表:Group,Person,和GroupPersonMap.GroupPersonMap是一个链接表,只包含主键Group和Person主键.我用VS 2010设计器创建了3个表的EF模型.EF很聪明,可以假设它GroupPersonMap是一个链接表,因此它不会在设计器中显示它.我想使用我现有的域对象而不是EF生成的类,所以我关闭了模型的代码生成.
我与EF模型匹配的现有类如下:
public class Group
{
public int GroupId { get; set; }
public string Name { get; set; }
public virtual ICollection<Person> People { get; set; }
}
public class Person
{
public int PersonId {get; set; }
public string FirstName { get; set; }
public virtual ICollection<Group> Groups { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我有一个通用的存储库接口,如下所示:
public interface IRepository<T> where T: class …Run Code Online (Sandbox Code Playgroud) c# domain-driven-design aggregateroot repository-pattern entity-framework-4.1
我刚刚开始考虑通过索引优化我的查询,因为SQL数据正在快速增长.我查看了优化器如何通过SSMS中的执行计划处理我的查询,并注意到正在使用Sort运算符.我听说Sort操作符表示查询中的设计不好,因为可以通过索引提前进行排序.所以这里是一个示例表和数据类似于我正在做的事情:
IF OBJECT_ID('dbo.Store') IS NOT NULL DROP TABLE dbo.[Store]
GO
CREATE TABLE dbo.[Store]
(
[StoreId] int NOT NULL IDENTITY (1, 1),
[ParentStoreId] int NULL,
[Type] int NULL,
[Phone] char(10) NULL,
PRIMARY KEY ([StoreId])
)
INSERT INTO dbo.[Store] ([ParentStoreId], [Type], [Phone]) VALUES (10, 0, '2223334444')
INSERT INTO dbo.[Store] ([ParentStoreId], [Type], [Phone]) VALUES (10, 0, '3334445555')
INSERT INTO dbo.[Store] ([ParentStoreId], [Type], [Phone]) VALUES (10, 1, '0001112222')
INSERT INTO dbo.[Store] ([ParentStoreId], [Type], [Phone]) VALUES (10, 1, '1112223333')
GO
Run Code Online (Sandbox Code Playgroud)
这是一个示例查询:
SELECT [Phone]
FROM [dbo].[Store] …Run Code Online (Sandbox Code Playgroud) 我对存储库模式和依赖注入很新.我遇到的几乎所有存储库模式都有某种GetAll()方法,如下所示:
public interface IRepository<T>
{
IQueryable<T> GetAll();
// other CRUD methods here...
}
Run Code Online (Sandbox Code Playgroud)
我在实现此接口和GetAll()方法时遇到问题,因为我正在调用一个存储过程,该存储过程需要一个基于用户输入而更改的参数.我不想在存储库接口中添加ad-hoc方法,例如IQueryable<T> GetAll(string input);.我也不想在构造函数中添加一个参数,因为它对我来说有点乱:
public class ConcreteRepository : IRepository<Entity>
{
string _storedProcedureInput;
public ConcreteRepository(string storedProcedureInput)
{
_storedProcedureInput = storedProcedureInput;
public IQueryable<Entity> GetAll()
{
// Call to stored procedure goes here passing in the
// _storedProcedureInput variable.
}
}
Run Code Online (Sandbox Code Playgroud)
我也使用依赖注入,所以我必须在绑定时向构造函数添加一些动态输入:
Bind<IRepository<Entity>>().To<ConcreteRepository>().WithConstructorArgument(?)
Run Code Online (Sandbox Code Playgroud)
有什么建议?
更新:
我想重用IRepository接口.例如,在一个程序中,我使用EF4实现GetAll()方法,而在另一个程序中,我使用标准ADO.NET来调用存储过程,如上例所示.
c# stored-procedures dependency-injection repository-pattern