存储过程的存储库模式

时间:2011-08-04 07:16:18

标签: c# stored-procedures dependency-injection repository-pattern

我对存储库模式和依赖注入很新。我遇到的几乎所有存储库模式都有某种GetAll()方法,如下所示:

public interface IRepository<T>
{
    IQueryable<T> GetAll();
    // other CRUD methods here...
}

我在实现此接口和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.
    }
}

我也使用依赖注入,所以在绑定时我必须向构造函数添加一些动态输入:

Bind<IRepository<Entity>>().To<ConcreteRepository>().WithConstructorArgument(?)

有什么建议吗?

更新

我想重用IRepository接口。例如,在一个程序中,我使用EF4实现GetAll()方法,而在另一个程序中,我使用标准ADO.NET来调用存储过程,如上例所示。

3 个答案:

答案 0 :(得分:5)

听起来你的GetAll并不一定能得到所有。在这种情况下,您也可以重命名它,或者使用另一种方法更准确地描述存储过程提供的功能,该方法采用可以传递给过程的适当输入参数。

答案 1 :(得分:5)

您无法在存储库中添加新方法来执行自定义存储过程:

    /// <summary>
    /// Execute Stored Proc with result set returned.
    /// </summary>
    /// <param name="procName"></param>
    /// <returns>An object resultset</returns>
    T ExecuteCustomStoredProc<T>(string procName, SqlParameter params);

并且在您的实现(具体存储库)中,您可以将此逻辑放在其中:

        public T ExecuteCustomStoredProc<T>(string commandName, SqlParameter params)
        {
            return this._repositoryContext.ObjectContext.ExecuteStoreQuery<T>(commandName, params);
        }

答案 2 :(得分:3)

我建议如果你将GetAll与存储过程一起使用,那你就错过了这一点。

返回IQueryable的GetAll示例以某种形式推断延迟执行,但如果您正在调用存储过程,则不会延迟执行。

我建议保留GetAll函数,但是要调用ORM的上下文。您对存储过程的调用,作为单独的方法保留,但返回IList<Entity>

之类的内容