如何在Asp.Net Core中集成ABP Dapper
在实际的项目中,除了集成ABP框架的EntityFrameworkCore以外,在有些特定的场景下不可避免地会使用一些SQL查询语句,一方面是由于现在的EntityFrameworkCore2.X有些问题没有解决,另外一方面是基于性能方面的考虑,在了解本篇内容之前,首先还是来看看官方文档来给出的说明。
按照官方的介绍整体可以分为下面的步骤:1安装依赖包。2添加DependsOn属性标签。3EntitytoTableMapping。4Usage通过上面的4个步骤我们就能够正常在Asp.NetCore项目中使用ABPDapper了,下面我们就具体的过程来做进一步的说明。
一安装包依赖
这个不做过多的解释,通过Nuget包管理器或者通过程序包管理控制台来添加Abp.Dapper的引用,在我们实际的项目中整个类库的结构如下图所示,包含Dapper和EntityFrameworkCore两种方案。
二添加DependsOn属性标签
后面我们就需要在我们当前类库项目中唯一的SalesDataModule中来做一些初始化和添加DependsOn标签的操作了。
[DependsOn(typeof(AbpZeroCoreEntityFrameworkCoreModule))] [DependsOn(typeof(AbpDapperModule))] publicclassSalesDataModule:AbpModule{ publicoverridevoidInitialize(){ IocManager.RegisterAssemblyByConvention(typeof(SalesDataModule).GetAssembly()); DapperExtensions.DapperExtensions.SetMappingAssemblies(newList{typeof(SalesDataModule).GetAssembly()}); } }
这里我们应该了解为什么要添加依赖关系?这个我们当前的SalesDataModule会依赖于AbpDapperModule和AbpZeroCoreEntityFrameworkCoreModule,确立了这样的依赖关系后,在ABP框架中就会将当前Module所依赖的其它Module放到List
publicvirtualvoidStartModules() { varsortedModules=_modules.GetSortedModuleListByDependency(); sortedModules.ForEach(module=>module.Instance.PreInitialize()); sortedModules.ForEach(module=>module.Instance.Initialize()); sortedModules.ForEach(module=>module.Instance.PostInitialize()); }
这个里面sortedModules就是通过这种依赖关系进行拓扑排序的,然后依次这行每个模块中的这几个方法进行一些初始化的操作。
三EntitytoTableMapping
这个按照官方的解释就是在建立Entity和数据库实体之间的关系,这个类似于在Domain层实体上面添加【Table】标签(个人理解),在这个里面我们还能添加一些其它特性,比如Ignore掉一些导航属性等等......
publicsealedclassVehicleOrderPlanMapper:ClassMapper{ publicVehicleOrderPlanMapper(){ Table("VehicleOrderPlan"); Map(x=>x.Branch).Ignore(); AutoMap(); } }
四应用
这个部分就结合具体的项目来谈一谈一些细节方面的东西,我们先来看看具体的代码。
publicclassVehicleOrderPlanDapperRepository:DcsDapperRepositoryBase,IVehicleOrderPlanDapperRepository{ publicVehicleOrderPlanDapperRepository(IActiveTransactionProvideractiveTransactionProvider):base(activeTransactionProvider){ } publicIEnumerable GetWeeklyOrderPlanSummary(int?yearOfPlan,int?weekOfPlan,stringprovinceName, [CanBeNull]VehicleOrderPlanType[]planType,stringmarketName,PageRequestpage){ varsqlParam=newStringBuilder() .AppendIf(yearOfPlan.HasValue,$"ANDp.YearOfPlan=:{nameof(yearOfPlan)}") .AppendIf(weekOfPlan.HasValue,$"ANDp.WeekOfPlan=:{nameof(weekOfPlan)}") .AppendIf(!provinceName.IsNullOrWhiteSpace(),$@"ANDEXISTS(SELECT1 FROMCompanyCWHEREc.Id=p.DealerIdANDc.Status<>{(int)MasterDataStatus.作废} ANDc.ProvinceNamelike'%'||:{nameof(provinceName)}||'%')"); varplanTypes=new[]{ VehicleOrderPlanType.周度计划, VehicleOrderPlanType.小品种计划, VehicleOrderPlanType.移库计划 }; if(planType!=null&&planType.Length>0) planTypes=planTypes.Intersect(planType).ToArray(); vardepartmentParam=string.Empty; if(!marketName.IsNullOrWhiteSpace()) departmentParam=$"AND(m.NameLIKE'%'||:{nameof(marketName)}||'%')"; varsql=$@" SELECTp.YearOfPlan,p.WeekOfPlan,TRUNC(p.CreateTime)ASCreateTime,TRUNC(p.StartTime)ASStartTime,TRUNC(p.EndTime)ASEndTime, pd.ProductCode,pd.ProductName,pd.ProductType,pd.ProductCategoryCodeASVehicleModelCode,pd.ProductCategoryNameASVehicleModelName, Sum(pd.PlannedQuantity)ASPlannedQuantity,Sum(pd.FirstPlannedQuantity)ASFirstPlannedQuantity, Sum(pd.QuantityOfAssessment)ASQuantityOfAssessment,Sum(pd.ConfirmedQuantity)ASConfirmedQuantity FROMVehicleOrderPlanp CROSSJOINVehicleOrderPlanDetailpd WHERE(p.Status<>{(int)VehicleOrderPlanStatus.作废}ANDp.Typein{planTypes.ToSqlInParam()}{sqlParam}ANDEXISTS( SELECT1 FROMDealerMarketDptRelationdm WHERE(((dm.BranchId=p.BranchId)AND(dm.DealerId=p.DealerId))AND(dm.Status={(int)BaseDataStatus.有效}))ANDEXISTS( SELECT1 FROMMarketingDepartmentm WHERE((m.BranchCode={SunlightConsts.DEFAULT_BRANCH_QRSALESLTD})AND(m.Status={(int)BaseDataStatus.有效})){departmentParam} AND(m.Id=dm.MarketId))))AND(p.Id=pd.VehicleOrderPlanId) GROUPBYp.YearOfPlan,p.WeekOfPlan,TRUNC(p.CreateTime),TRUNC(p.StartTime),TRUNC(p.EndTime),pd.ProductCode, pd.ProductName,pd.ProductType,pd.ProductCategoryCode,pd.ProductCategoryName"; returnQueryPaged (sql,page,new{ yearOfPlan, weekOfPlan, provinceName, marketName }); } }
这段代码主要是通过具体传入的参数计划年、计划周、省份......等参数到数据库中查询相关的记录,这里我们先看看基类DcsDapperRepositoryBase
publicclassDcsDapperRepositoryBase:DapperEfRepositoryBase whereTEntity:class,IEntity { publicDcsDapperRepositoryBase(IActiveTransactionProvideractiveTransactionProvider):base(activeTransactionProvider){ } /// ///以分页的形式查询数据 /// ////// /// /// 参数的匿名对象 /// protectedIEnumerable QueryPaged (stringsql,PageRequestpageRequest,objectparameters=null) whereTValueObject:ValueObjectBase{ varorderCondition=(string.IsNullOrWhiteSpace(pageRequest.Ordering)?string.Empty:"ORDERBY"+pageRequest.Ordering); orderCondition.SqlInjectionInspect(); varpagedSql=$@"WITH""_data""AS({sql}), ""_count""AS(SELECTCOUNT(0)ASOverallCountFROM""_data"") SELECT* FROM(SELECTA.*,ROWNUMAS""RowNum"" FROM(SELECT*FROM""_data"" {orderCondition})A WHEREROWNUM<={pageRequest.PageSize*(pageRequest.PageIndex+1)})B, ""_count"" WHERE""RowNum"">{pageRequest.PageSize*pageRequest.PageIndex}"; returnQuery (pagedSql,parameters); } }
在这个基类中我们继承了ABP中的基类DapperEfRepositoryBase
在处理完这些后,我们再来看看当前VehicleOrderPlanRepository继承的接口是在哪里进行定义的?具体的领域层又该如何进行调用?
publicinterfaceIVehicleOrderPlanDapperRepository:IDapperRepository{ IEnumerable GetWeeklyOrderPlanSummary(int?yearOfPlan,int?weekOfPlan,stringprovinceName, [CanBeNull]VehicleOrderPlanType[]planType,stringmarketName,PageRequestpage); }
这个接口非常简单,但是这个接口究竟应该在哪里进行定义呢?我们按照DDD思想,首先想到的就是在领域层进行定义,不然领域层其它业务该在哪里调用这个方法呢?那么这个可以从哪里找到答案呢?
有没有对这张图很熟悉,这个就是用于介绍ABPN层架构的示意图,红框标注的就是具体的结构中的接口定义和实现,这两者的定义和实现分别是处于不同的层中,一个属于DomainLayer中而具体的实现位于InfrastructureLayer中,一层定义接口,而另外一层则定义具体的实现,有了这个你是不是对整个ABP的架构有了更深入的理解呢?
以上就是如何在Asp.NetCore中集成ABPDapper的详细内容,更多关于Asp.NetCore中集成ABPDapper的资料请关注毛票票其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。