内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

如何在Asp.Net項(xiàng)目中使用ABPDapper-創(chuàng)新互聯(lián)

如何在Asp.Net項(xiàng)目中使用ABP Dapper?針對這個問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括懷化網(wǎng)站建設(shè)、懷化網(wǎng)站制作、懷化網(wǎng)頁制作以及懷化網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,懷化網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到懷化省份的部分城市,未來相信會繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

一 安裝包依賴


這個不做過多的解釋,通過Nuget 包管理器或者通過程序包管理控制臺來添加Abp.Dapper的引用,在我們實(shí)際的項(xiàng)目中整個類庫的結(jié)構(gòu)如下圖所示,包含Dapper和EntityFrameworkCore兩種方案。

如何在Asp.Net項(xiàng)目中使用ABP Dapper

二 添加DependsOn屬性標(biāo)簽

后面我們就需要在我們當(dāng)前類庫項(xiàng)目中的SalesDataModule中來做一些初始化和添加DependsOn標(biāo)簽的操作了。

[DependsOn(typeof(AbpZeroCoreEntityFrameworkCoreModule))]
    [DependsOn(typeof(AbpDapperModule))]
    public class SalesDataModule : AbpModule {
        public override void Initialize() {         
            IocManager.RegisterAssemblyByConvention(typeof(SalesDataModule).GetAssembly());
            DapperExtensions.DapperExtensions.SetMappingAssemblies(new List<Assembly> { typeof(SalesDataModule).GetAssembly() });
        }
    }

這里我們應(yīng)該了解為什么要添加依賴關(guān)系?這個我們當(dāng)前的SalesDataModule會依賴于AbpDapperModule和AbpZeroCoreEntityFrameworkCoreModule,確立了這樣的依賴關(guān)系后,在ABP框架中就會將當(dāng)前Module所依賴的其它Module放到List<AbpModule>的前面,這樣通過這樣對的層層依賴關(guān)系進(jìn)行拓?fù)渑判蚓湍軌虮WC被依賴的AbpModule一定先進(jìn)行初始化操作,這樣就能夠避免引用關(guān)系的錯誤,從而導(dǎo)致代碼邏輯的錯誤,具體說來:如果A 依賴于B,B依賴于C,那么這三個模塊之間的排序?yàn)镃 B A,這樣在整個Module系統(tǒng)初始化的時候,會先執(zhí)行Module C的PreIntialize()、Initialize()、PostInitialize()方法,我們看看ABP中的源碼。

public virtual void StartModules()
      {
          var sortedModules = _modules.GetSortedModuleListByDependency();
          sortedModules.ForEach(module => module.Instance.PreInitialize());
          sortedModules.ForEach(module => module.Instance.Initialize());
          sortedModules.ForEach(module => module.Instance.PostInitialize());
      }

這個里面sortedModules就是通過這種依賴關(guān)系進(jìn)行拓?fù)渑判虻?,然后依次這行每個模塊中的這幾個方法進(jìn)行一些初始化的操作。

三 Entity to Table Mapping

這個按照官方的解釋就是在建立Entity和數(shù)據(jù)庫實(shí)體之間的關(guān)系,這個類似于在Domain層實(shí)體上面添加【Table】標(biāo)簽(個人理解),在這個里面我們還能添加一些其它特性,比如Ignore掉一些導(dǎo)航屬性等等......

public sealed class VehicleOrderPlanMapper : ClassMapper<VehicleOrderPlan> {
    public VehicleOrderPlanMapper() {
        Table("VehicleOrderPlan");
        Map(x => x.Branch).Ignore();
        AutoMap();
    }
}

四 應(yīng)用

這個部分就結(jié)合具體的項(xiàng)目來談一談一些細(xì)節(jié)方面的東西,我們先來看看具體的代碼。

public class VehicleOrderPlanDapperRepository : DcsDapperRepositoryBase<VehicleOrderPlan>, IVehicleOrderPlanDapperRepository {
        public VehicleOrderPlanDapperRepository(IActiveTransactionProvider activeTransactionProvider) : base(activeTransactionProvider) {
        }
 
        public IEnumerable<WeeklyOrderPlanSummary> GetWeeklyOrderPlanSummary(int? yearOfPlan, int? weekOfPlan, string provinceName,
            [CanBeNull]VehicleOrderPlanType[] planType, string marketName, PageRequest page) {
            var sqlParam = new StringBuilder()
                .AppendIf(yearOfPlan.HasValue, $" AND p.YearOfPlan = :{nameof(yearOfPlan)}")
                .AppendIf(weekOfPlan.HasValue, $" AND p.WeekOfPlan = :{nameof(weekOfPlan)}")
                .AppendIf(!provinceName.IsNullOrWhiteSpace(), $@" AND EXISTS ( SELECT 1
    FROM Company C WHERE c.Id = p.DealerId AND c.Status <> {(int)MasterDataStatus.作廢}
        AND c.ProvinceName like '%' || :{nameof(provinceName)} || '%')");
 
            var planTypes = new[] {
                VehicleOrderPlanType.周度計(jì)劃,
                VehicleOrderPlanType.小品種計(jì)劃,
                VehicleOrderPlanType.移庫計(jì)劃
            };
            if (planType != null && planType.Length > 0)
                planTypes = planTypes.Intersect(planType).ToArray();
 
            var departmentParam = string.Empty;
            if (!marketName.IsNullOrWhiteSpace())
                departmentParam = $" AND (m.Name LIKE '%' || :{nameof(marketName)} || '%')";
 
            var sql = $@"
SELECT p.YearOfPlan, p.WeekOfPlan, TRUNC(p.CreateTime) AS CreateTime, TRUNC(p.StartTime) AS StartTime, TRUNC(p.EndTime) AS EndTime,
       pd.ProductCode, pd.ProductName, pd.ProductType, pd.ProductCategoryCode AS VehicleModelCode, pd.ProductCategoryName AS VehicleModelName,
       Sum(pd.PlannedQuantity) AS PlannedQuantity, Sum(pd.FirstPlannedQuantity) AS FirstPlannedQuantity,
       Sum(pd.QuantityOfAssessment) AS QuantityOfAssessment, Sum(pd.ConfirmedQuantity) AS ConfirmedQuantity
FROM VehicleOrderPlan p
CROSS JOIN VehicleOrderPlanDetail pd
WHERE (p.Status <> {(int)VehicleOrderPlanStatus.作廢} AND p.Type in {planTypes.ToSqlInParam()} {sqlParam} AND EXISTS (
    SELECT 1
    FROM DealerMarketDptRelation dm
    WHERE (((dm.BranchId = p.BranchId) AND (dm.DealerId = p.DealerId)) AND (dm.Status = {(int)BaseDataStatus.有效})) AND EXISTS (
        SELECT 1
        FROM MarketingDepartment m
        WHERE ((m.BranchCode = {SunlightConsts.DEFAULT_BRANCH_QRSALESLTD}) AND (m.Status = {(int)BaseDataStatus.有效})) {departmentParam}
            AND (m.Id = dm.MarketId)))) AND (p.Id = pd.VehicleOrderPlanId)
GROUP BY p.YearOfPlan, p.WeekOfPlan, TRUNC(p.CreateTime), TRUNC(p.StartTime), TRUNC(p.EndTime), pd.ProductCode,
         pd.ProductName, pd.ProductType, pd.ProductCategoryCode, pd.ProductCategoryName";
 
            return QueryPaged<WeeklyOrderPlanSummary>(sql, page, new {
                yearOfPlan,
                weekOfPlan,
                provinceName,
                marketName
            });
        }
    }

這段代碼主要是通過具體傳入的參數(shù)計(jì)劃年、計(jì)劃周、省份......等參數(shù)到數(shù)據(jù)庫中查詢相關(guān)的記錄,這里我們先看看基類DcsDapperRepositoryBase<VehicleOrderPlan>里面做了些什么?

public class DcsDapperRepositoryBase<TEntity> : DapperEfRepositoryBase<DcsDbContext, TEntity>
        where TEntity : class, IEntity<int> {
        public DcsDapperRepositoryBase(IActiveTransactionProvider activeTransactionProvider) : base(activeTransactionProvider) {
        }
 
        /// <summary>
        /// 以分頁的形式查詢數(shù)據(jù)
        /// </summary>
        /// <typeparam name="TValueObject"></typeparam>
        /// <param name="sql"></param>
        /// <param name="pageRequest"></param>
        /// <param name="parameters">參數(shù)的匿名對象</param>
        /// <returns></returns>
        protected IEnumerable<TValueObject> QueryPaged<TValueObject>(string sql, PageRequest pageRequest, object parameters = null)
            where TValueObject : ValueObjectBase {
            var orderCondition = (string.IsNullOrWhiteSpace(pageRequest.Ordering) ? string.Empty : "ORDER BY " + pageRequest.Ordering);
            orderCondition.SqlInjectionInspect();
            var pagedSql = $@"WITH ""_data"" AS ({sql}),
     ""_count"" AS (SELECT COUNT(0) AS OverallCount FROM ""_data"")
SELECT *
FROM (SELECT A.*, ROWNUM AS ""RowNum""
      FROM (SELECT * FROM ""_data""
            {orderCondition}) A
      WHERE ROWNUM <= {pageRequest.PageSize * (pageRequest.PageIndex + 1)}) B,
     ""_count""
WHERE ""RowNum"" > {pageRequest.PageSize * pageRequest.PageIndex}";
            return Query<TValueObject>(pagedSql, parameters);
        }
    }

在這個基類中我們繼承了ABP中的基類DapperEfRepositoryBase<DcsDbContext, TEntity>,這個泛型基類第一個參數(shù)就是我們項(xiàng)目中的具體DbContext,第二個參數(shù)就是我們具體定義的實(shí)體,這個實(shí)體是主鍵為Int的自增長類型。這里面由于查詢的數(shù)據(jù)非常多,所以我們這里實(shí)際上返回的是分頁的第一頁的結(jié)果集,這里還有一個重要的知識就是,為了防止sql注入,這里sql中的參數(shù)都采用參數(shù)的匿名對象,而不是直接進(jìn)行拼接,這個是防止SQL注入的時候最常見的方式。通過這個具體的例子你應(yīng)該知道怎樣在ABP Dapper中使用匿名參數(shù)對象來防止SQL注入,另外通過這段SQL你還知道在Oracle數(shù)據(jù)庫中如何對查詢到的結(jié)果進(jìn)行分頁處理。

在處理完這些后,我們再來看看當(dāng)前VehicleOrderPlanRepository繼承的接口是在哪里進(jìn)行定義的?具體的領(lǐng)域?qū)佑衷撊绾芜M(jìn)行調(diào)用?

public interface IVehicleOrderPlanDapperRepository : IDapperRepository<VehicleOrderPlan> {
       IEnumerable<WeeklyOrderPlanSummary> GetWeeklyOrderPlanSummary(int? yearOfPlan, int? weekOfPlan, string provinceName,
           [CanBeNull] VehicleOrderPlanType[] planType, string marketName, PageRequest page);
   }

這個接口非常簡單,但是這個接口究竟應(yīng)該在哪里進(jìn)行定義呢?我們按照DDD思想,首先想到的就是在領(lǐng)域?qū)舆M(jìn)行定義,不然領(lǐng)域?qū)悠渌鼧I(yè)務(wù)該在哪里調(diào)用這個方法呢?那么這個可以從哪里找到答案呢?

如何在Asp.Net項(xiàng)目中使用ABP Dapper

關(guān)于如何在Asp.Net項(xiàng)目中使用ABP Dapper問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識。

名稱欄目:如何在Asp.Net項(xiàng)目中使用ABPDapper-創(chuàng)新互聯(lián)
URL地址:http://www.rwnh.cn/article42/ceiphc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)、域名注冊網(wǎng)站制作、軟件開發(fā)動態(tài)網(wǎng)站、搜索引擎優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站建設(shè)
太白县| 收藏| 米林县| 喀喇| 吉木乃县| 深泽县| 彭水| 麻江县| 长治市| 临汾市| 时尚| 巩义市| 沈丘县| 塔城市| 道孚县| 黄冈市| 晋州市| 海口市| 措勤县| 外汇| 乌什县| 景宁| 荔浦县| 岳西县| 徐汇区| 伊春市| 神池县| 东丰县| 克什克腾旗| 武清区| 甘德县| 通海县| 甘肃省| 杂多县| 禄丰县| 故城县| 枣强县| 郸城县| 沁水县| 武宁县| 佳木斯市|