使用 EFCore 创建用于从存储过程返回数据的通用存储库
Create generic repository for returning data from stored procedure with EFCore
我正在尝试使用 aspnetboilerplate 框架创建一个通用的自定义存储库。我希望存储库能够调用 SQL 服务器中的存储过程和 return 一组用于显式类型的数据。
自定义存储库:
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();
}
}
我将 return 类型添加到 DbContext 中:
public virtual DbSet<PMTestSP> PMTestSP { get; set; }
当我调用 GetTestSP 时,出现此错误:
ArgumentNullException: Value cannot be null. Parameter name:
unitOfWork
Abp.EntityFrameworkCore.Uow.UnitOfWorkExtensions.GetDbContext(IActiveUnitOfWork
unitOfWork, Nullable multiTenancySide)
Abp.EntityFrameworkCore.Uow.UnitOfWorkDbContextProvider.GetDbContext(Nullable
multiTenancySide)
Abp.EntityFrameworkCore.Uow.UnitOfWorkDbContextProvider.GetDbContext()
Company.Name.EntityFrameworkCore.Repositories.PMStoredProcedureRepository..ctor(IDbContextProvider
dbContextProvider) in PMStoredProcedureRepository.cs
+
Context = dbContextProvider.GetDbContext(); Castle.Proxies.PMStoredProcedureRepository`1Proxy..ctor(IInterceptor[]
, IDbContextProvider )
添加 [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();
}
}
我认为问题是您的自定义存储库没有获得正确的 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>
。你可以试试这个。
我正在尝试使用 aspnetboilerplate 框架创建一个通用的自定义存储库。我希望存储库能够调用 SQL 服务器中的存储过程和 return 一组用于显式类型的数据。
自定义存储库:
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();
}
}
我将 return 类型添加到 DbContext 中:
public virtual DbSet<PMTestSP> PMTestSP { get; set; }
当我调用 GetTestSP 时,出现此错误:
ArgumentNullException: Value cannot be null. Parameter name: unitOfWork Abp.EntityFrameworkCore.Uow.UnitOfWorkExtensions.GetDbContext(IActiveUnitOfWork unitOfWork, Nullable multiTenancySide) Abp.EntityFrameworkCore.Uow.UnitOfWorkDbContextProvider.GetDbContext(Nullable multiTenancySide) Abp.EntityFrameworkCore.Uow.UnitOfWorkDbContextProvider.GetDbContext() Company.Name.EntityFrameworkCore.Repositories.PMStoredProcedureRepository..ctor(IDbContextProvider dbContextProvider) in PMStoredProcedureRepository.cs + Context = dbContextProvider.GetDbContext(); Castle.Proxies.PMStoredProcedureRepository`1Proxy..ctor(IInterceptor[] , IDbContextProvider )
添加 [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();
}
}
我认为问题是您的自定义存储库没有获得正确的 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>
。你可以试试这个。