在ABP中访问数据通常通过Repository进行,一般不需要直接使用DbContext,但有时我们需要通过直接使用DbContext进行复杂得查询。这时需要注意以下几点:
- 通过使用IDbContextProvider获取DbContext,而不是直接实例化DbContext
- 使用DbContext的方法必须是UnitOfWork
- 在方法中使用DbContext时,不能使用using{}
ABP通过IDbContextProvider获取DbContext,IDbContextProvider可以通过依赖注入获得。比如:
private readonly IDbContextProvider<MyFlowDbContext> _dbContextprovider;
public QueryEntity(IDbContextProvider<MyFlowDbContext> dbContextProvider)
{
_dbContextprovider = dbContextProvider;
}
获取DbContext时的代码如下:
var ctx = _dbContextprovider.GetDbContext();
在使用EF编程时,如果需要使用DbContext,通常需要将代码放在using{}块中,比如:
using (var context = LocalIocManager.Resolve<MyFlowDbContext>())
{
context.DisableAllFilters();
result = func(context);
context.SaveChanges();
}
这样做是确保context被及时关闭,但在APB的UnitOfWork中这样使用会出现错误,因为ABP在完成你所需要的操作后,还需要进行跟踪记录等后续处理,还需要context保持活动状态。这时,直接使用DbContext就可以,下面是一个例子:
using Abp.Domain.Services;
using Abp.Domain.Uow;
using Abp.EntityFramework;
using jiagoushi_cn.MyFlow.Core.QueryEntities;
using jiagoushi_cn.MyFlow.Core.Services;
using System.Collections.Generic;
using System.Linq;
namespace jiagoushi_cn.MyFlow.EntityFramework
{
public class QueryEntity : DomainService, IQueryEntity
{
private readonly IDbContextProvider<MyFlowDbContext> _dbContextprovider;
public QueryEntity(IDbContextProvider<MyFlowDbContext> dbContextProvider)
{
_dbContextprovider = dbContextProvider;
}
[UnitOfWork]
public IEnumerable<StateVariableQuery> GetStateVariables(string processName, string stateName)
{
var ctx = _dbContextprovider.GetDbContext();
IQueryable<StateVariableQuery> l = from p in ctx.StateVariables
from q in ctx.StateNodes
where p.StateNodeId == q.Id
from f in ctx.ProcessModels
where f.Id == q.ProcessModelId && f.ProcessName == processName && q.StateName == stateName
from pv in ctx.ProcessVariables
where pv.ProcessModelId == q.ProcessModelId && pv.VariableName == p.VariableName
select new StateVariableQuery
{
Id = p.Id,
DefaultValue = p.DefaultValue,
DisplayOrder = p.DisplayOrder,
IsEditable = p.IsEditable,
StateNodeId = p.StateNodeId,
VariableName = p.VariableName,
VariableType = pv.VariableType
};
return l.ToList();
}
}
}