2017-10-12 282 views
0

我想創建一個通用的自定義存儲庫使用aspnetboilerplate框架。我希望存儲庫能夠調用SQL Server中的存儲過程並返回一組數據以用於顯式類型。創建通用存儲庫從存儲過程返回數據與EFCore

自定義庫:

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: 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)

+0

有一篇關於如何使用APB執行存儲過程的文章。 https://www.codeproject.com/Articles/1199648/Using-Stored-Procedure-User-Defined-Function-and-V –

+0

該文章將存儲庫綁定到顯式類型。我希望在調用存儲過程時保持存儲庫的通用性,以便與實體的過程返回相匹配。 – user1104087

回答

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(); 
    } 
} 
+0

這種方法沒有運氣,在自定義存儲庫中分配上下文時仍然會出現相同的錯誤:Context = dbContextProvider.GetDbContext();出於某種原因,unitOfWork爲空,所以我不確定如何準確獲取dbcontext。 – user1104087

+0

控制器。當我以某種方式注入時,是否可以將dbcontext從應用程序服務傳遞到存儲庫? – user1104087

+0

應用程序服務注入到控制器的構造函數中。應用服務可以與其他方法一起使用。如上所示,存儲的proc存儲庫也被注入到應用服務的構造函數中。 – user1104087

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>。你可以試試這個。