Reputation: 57
I'm trying to create a generic custom repository using the aspnetboilerplate framework. I want the repository to be able to call a stored procedure in SQL Server and return a set of data for use with an explicit type.
Custom repository:
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;
}
}
What my app service looks like:
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();
}
}
I added the return type to the DbContext as:
public virtual DbSet<PMTestSP> PMTestSP { get; set; }
When I call GetTestSP, I get this error:
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 )
Upvotes: 2
Views: 3004
Reputation: 165
I think the issue is your custom repository don't get right dbcontext. Look at document 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
}
Note: the custom repository must inherit EfRepositoryBase<SimpleTaskSystemDbContext, TEntity, TPrimaryKey>
. You could try this.
Upvotes: 0
Reputation: 43098
Add [UnitOfWork]
attribute and make it a virtual
method:
[UnitOfWork]
public virtual List<PMTestSP> GetTestSP()
{
// ...
}
You can inject IUnitOfWorkManager
to begin a UnitOfWork
explicitly:
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();
}
}
Upvotes: 2