ABP中直接使用DbContext

在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();

        }
    }
}

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容