【问题标题】:Repository Pattern with Stored Procedures存储过程的存储库模式
【发布时间】:2011-08-04 07:16:17
【问题描述】:

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

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

我在实现此接口和 GetAll() 方法时遇到问题,因为我正在调用一个存储过程,该过程需要根据用户输入更改的参数。我不想向存储库接口添加临时方法,例如IQueryable&lt;T&gt; 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 来调用上面示例中的存储过程。

【问题讨论】:

  • 您的代码看起来绝对没问题,并且符合存储库模式。

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


【解决方案1】:

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

【讨论】:

  • 这是否意味着我需要向存储库接口添加另一种方法,例如IQueryable&lt;T&gt; StoredProcedureMethod(string input)?当需要重用存储库接口时,很有可能不会实现 StoredProcedureMethod()。
  • @jodev 这取决于您的 SP 实际在做什么 - 听起来它正在返回所有记录的子集。您总是可以尝试通过使用 GetAllMatches(SomeMatchingObject 标准) 来抽象出输入。不知道 SP 做什么,很难进一步评论。
  • 谢谢。我正在返回一个子集,所以像你建议的另一种方法应该处理调用是有道理的。
  • 你不需要将它添加到通用接口中;您可以将其添加到特定界面。像这样: IOrderRepository : IRepository { 这里的附加方法}。然后,您可以使用 DI 确保当有人请求 IRepository 时,他们会获得 IOrderRepository 及其附加方法。当然,需要这些额外方法的客户可以直接请求。
【解决方案2】:

你不能在你的 IRepository 中添加一个新方法来执行自定义存储过程吗:

    /// <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);

在你的实现(ConcreteRepository)中你可以把这个逻辑放在它上面:

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

【讨论】:

    【解决方案3】:

    我建议,如果您将 GetAll 与存储过程一起使用,那么您有点忽略了这一点。

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

    我建议保留 GetAll 函数,但作为对 ORM 上下文的调用。您对存储过程的调用,作为单独的方法保存,但返回类似IList&lt;Entity&gt;

    【讨论】:

    • 感谢您的回复。我修改了我的帖子。我将对存储过程和 EF4 的 DbContext 使用 GetAll() 方法。
    猜你喜欢
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多