如何在Entity Framework中使用存储过程+存储库+工作模式单元?

sar*_*ari 12 entity-framework unit-of-work repository-pattern entity-framework-4 ef-code-first

我首先使用Entity Framework代码创建MVC Web应用程序项目.在这个项目中,我将使用通用存储库和工作单元模式.另外,我想使用存储过程来获取list by和get-list方法.

如何将存储过程与通用存储库和工作单元模式一起使用?

sun*_*nil 21

添加到您的通用存储库

public IEnumerable<T> ExecWithStoreProcedure(string query, params object[] parameters)
{
        return _context.Database.SqlQuery<T>(query, parameters);
}
Run Code Online (Sandbox Code Playgroud)

然后你就可以用任何unitofwork/repository来调用它

IEnumerable<Products> products = 
             _unitOfWork.ProductRepository.ExecWithStoreProcedure(
             "spGetProducts @bigCategoryId",
             new SqlParameter("bigCategoryId", SqlDbType.BigInt) { Value = categoryId } 
      );
Run Code Online (Sandbox Code Playgroud)

  • 但是,如果您的SP没有返回您的存储库映射到的实体,该怎么办?例如,我的SP可能会返回连接表的数据,或者只返回一个名为"Result"的整数值.在这种情况下,将上述示例与Product实体一起使用将是不够的,并打破了接口隔离原则.有任何想法吗? (6认同)

Chr*_*ton 8

您不应该尝试使用具有UoW/Repository模式的SP,因为它们很难在代码中控制,并且通常不会映射回相同的实体类型.UoW和Repository模式更适合直接使用ADO.NET而不是Entity Framework,因为EF已经是Repository模式.在使用SP时,我建议将CQRS作为更好的模式.通过@sunil和我对它的评论来阐述答案,我创建了一个专门用于处理存储过程的类.它也很容易模拟和测试.

public class ProcedureManager : IProcedureManager
{
    internal DbContext Context;

    public ProcedureManager(DbContext context)
    {
        Context = context;
    }

    //When you expect a model back (async)
    public async Task<IList<T>> ExecWithStoreProcedureAsync<T>(string query, params object[] parameters)
    {
        return await Context.Database.SqlQuery<T>(query, parameters).ToListAsync();
    }

    //When you expect a model back
    public IEnumerable<T> ExecWithStoreProcedure<T>(string query)
    {
        return Context.Database.SqlQuery<T>(query);
    }

    // Fire and forget (async)
    public async Task ExecuteWithStoreProcedureAsync(string query, params object[] parameters)
    {
        await Context.Database.ExecuteSqlCommandAsync(query, parameters);
    }

    // Fire and forget
    public void ExecuteWithStoreProcedure(string query, params object[] parameters)
    {
        Context.Database.ExecuteSqlCommand(query, parameters);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为您应该删除您的编辑,因为您的答案现在包含虚假信息,人们会否决您的投票。如果我是您,我只会包括:*带有存储过程的 UOW 需要手动事务处理。*然后继续您在编辑之前的回答。 (3认同)
  • 当然不会。SP 无法遵守 UoW 模式,因为 UoW 模式适用于跟踪更改并批量执行操作的 ORM。该接口是将 SP 执行与可跟踪更改的 ORM 逻辑分离的有用方法。在回答 OP 问题时,您不应使用具有 UoW 模式的 SP。SP 实际上也不适合存储库模式,可能更适合 CQRS。 (2认同)