使用EFCore创建从存储过程返回数据的通用存储库

时间:2017-10-12 04:59:32

标签: c# asp.net asp.net-core-mvc aspnetboilerplate

我正在尝试使用aspnetboilerplate框架创建一个通用的自定义存储库。我希望存储库能够在SQL Server中调用存储过程并返回一组数据以供显式类型使用。

自定义存储库:

public class PMStoredProcedureRepository<T> : IPMStoredProcedureRepository<T> where T : class
{
    private MyDbContext Context { get; set; }

    public PMStoredProcedureRepository(IDbContextProvider<MyDbContext> dbContextProvider)
    {
        Context = dbContextProvider.GetDbContext();
    }

    // When you expect a model back (async)
    public IQueryable<T> ExecuteSP(string query, params object[] parameters)
    {
        var type = Context.Set<T>().FromSql(query, parameters);
        return type;
    }
}

我的应用服务是什么样的:

public class DashboardAppService : MyAppServiceBase, IDashboardAppService
{
    // Entity repositories
    private readonly IPMStoredProcedureRepository<PMTestSP> _storedProcRepository;

    public DashboardAppService(
        IPMStoredProcedureRepository<PMTestSP> storedProcRepository
        )
    {
        _storedProcRepository = storedProcRepository;
    }

    public List<PMTestSP> GetTestSP()
    {
        var ret = _storedProcRepository.ExecuteSP("exec pme_TestProcedure", new SqlParameter("inputString", "abcde"));
        return ret.ToList();
    }
}

我将返回类型添加到DbContext中:

public virtual DbSet<PMTestSP> PMTestSP { get; set; }

当我调用GetTestSP时,我收到此错误:

  

ArgumentNullException:值不能为null。参数名称:   的UnitOfWork   Abp.EntityFrameworkCore.Uow.UnitOfWorkExtensions.GetDbContext(IActiveUnitOfWork   unitOfWork,Nullable multiTenancySide)   Abp.EntityFrameworkCore.Uow.UnitOfWorkDbContextProvider.GetDbContext(可空   multiTenancySide)   Abp.EntityFrameworkCore.Uow.UnitOfWorkDbContextProvider.GetDbContext()   Company.Name.EntityFrameworkCore.Repositories.PMStoredProcedureRepository..ctor(IDbContextProvider   dbMStextProvider)在PMStoredProcedureRepository.cs中   +               Context = dbContextProvider.GetDbContext(); Castle.Proxies.PMStoredProcedureRepository`1Proxy..ctor(IInterceptor []   ,IDbContextProvider)

2 个答案:

答案 0 :(得分:1)

添加[UnitOfWork]属性并将其设为virtual方法:

[UnitOfWork]
public virtual List<PMTestSP> GetTestSP()
{
    // ...
}

您可以注入IUnitOfWorkManager以明确地开始UnitOfWork

public List<PMTestType> GetTestSP()
{
    using (var uow = UnitOfWorkManager.Begin())
    {
        var ret = _storedProcRepository.ExecuteSP("exec pme_TestProcedure", new SqlParameter("inputString", "abcde"));
        uow.Complete();
        return ret.ToList();
    }
}

答案 1 :(得分:0)

我认为问题是您的自定义存储库没有正确的dbcontext。查看文档Create custom repository

public class SimpleTaskSystemRepositoryBase<TEntity, TPrimaryKey> : EfRepositoryBase<SimpleTaskSystemDbContext, TEntity, TPrimaryKey>
    where TEntity : class, IEntity<TPrimaryKey>
{
    public SimpleTaskSystemRepositoryBase(IDbContextProvider<SimpleTaskSystemDbContext> dbContextProvider)
        : base(dbContextProvider)
    {
    }

    //add common methods for all repositories
}

注意:自定义存储库必须继承EfRepositoryBase<SimpleTaskSystemDbContext, TEntity, TPrimaryKey>。你可以试试这个。