国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - ASP.NET教程 - 如何在Asp.Net Core中集成ABP Dapper

如何在Asp.Net Core中集成ABP Dapper

2021-12-09 14:47Hello 尋夢者! ASP.NET教程

這篇文章主要介紹了如何在Asp.Net Core中集成ABP Dapper,幫助大家更好的理解和學習使用Asp.Net Core,感興趣的朋友可以了解下

  在實際的項目中,除了集成ABP框架的EntityFrameworkCore以外,在有些特定的場景下不可避免地會使用一些SQL查詢語句,一方面是由于現在的EntityFrameworkCore2.X有些問題沒有解決,另外一方面是基于性能方面的考慮,在了解本篇內容之前,首先還是來看看官方文檔來給出的說明。

  按照官方的介紹整體可以分為下面的步驟:1 安裝依賴包。2 添加DependsOn屬性標簽。3 Entity to Table Mapping。 4 Usage 通過上面的4個步驟我們就能夠正常在Asp.Net Core項目中使用ABP Dapper了,下面我們就具體的過程來做進一步的說明。

  一 安裝包依賴

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

如何在Asp.Net Core中集成ABP Dapper

  二 添加DependsOn屬性標簽

  后面我們就需要在我們當前類庫項目中唯一的SalesDataModule中來做一些初始化和添加DependsOn標簽的操作了。

?
1
2
3
4
5
6
7
8
[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() });
        }
    }

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

?
1
2
3
4
5
6
7
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就是通過這種依賴關系進行拓撲排序的,然后依次這行每個模塊中的這幾個方法進行一些初始化的操作。

  三 Entity to Table Mapping

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

?
1
2
3
4
5
6
7
public sealed class VehicleOrderPlanMapper : ClassMapper<VehicleOrderPlan> {
    public VehicleOrderPlanMapper() {
        Table("VehicleOrderPlan");
        Map(x => x.Branch).Ignore();
        AutoMap();
    }
}

  四 應用

  這個部分就結合具體的項目來談一談一些細節方面的東西,我們先來看看具體的代碼。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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.周度計劃,
                VehicleOrderPlanType.小品種計劃,
                VehicleOrderPlanType.移庫計劃
            };
            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
            });
        }
    }

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class DcsDapperRepositoryBase<TEntity> : DapperEfRepositoryBase<DcsDbContext, TEntity>
        where TEntity : class, IEntity<int> {
        public DcsDapperRepositoryBase(IActiveTransactionProvider activeTransactionProvider) : base(activeTransactionProvider) {
        }
 
        /// <summary>
        /// 以分頁的形式查詢數據
        /// </summary>
        /// <typeparam name="TValueObject"></typeparam>
        /// <param name="sql"></param>
        /// <param name="pageRequest"></param>
        /// <param name="parameters">參數的匿名對象</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>,這個泛型基類第一個參數就是我們項目中的具體DbContext,第二個參數就是我們具體定義的實體,這個實體是主鍵為Int的自增長類型。這里面由于查詢的數據非常多,所以我們這里實際上返回的是分頁的第一頁的結果集,這里還有一個重要的知識就是,為了防止sql注入,這里sql中的參數都采用參數的匿名對象,而不是直接進行拼接,這個是防止SQL注入的時候最常見的方式。通過這個具體的例子你應該知道怎樣在ABP Dapper中使用匿名參數對象來防止SQL注入,另外通過這段SQL你還知道在Oracle數據庫中如何對查詢到的結果進行分頁處理。

  在處理完這些后,我們再來看看當前VehicleOrderPlanRepository繼承的接口是在哪里進行定義的?具體的領域層又該如何進行調用?

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

  這個接口非常簡單,但是這個接口究竟應該在哪里進行定義呢?我們按照DDD思想,首先想到的就是在領域層進行定義,不然領域層其它業務該在哪里調用這個方法呢?那么這個可以從哪里找到答案呢?

如何在Asp.Net Core中集成ABP Dapper

  有沒有對這張圖很熟悉,這個就是用于介紹ABP N層架構的示意圖,紅框標注的就是具體的結構中的接口定義和實現,這兩者的定義和實現分別是處于不同的層中,一個屬于Domain Layer中而具體的實現位于Infrastructure Layer中,一層定義接口,而另外一層則定義具體的實現,有了這個你是不是對整個ABP的架構有了更深入的理解呢?

以上就是如何在Asp.Net Core中集成ABP Dapper的詳細內容,更多關于Asp.Net Core中集成ABP Dapper的資料請關注服務器之家其它相關文章!

原文鏈接:https://www.cnblogs.com/seekdream/p/10790615.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产一区二 | 久久久久黄 | 日韩影片在线观看 | 国产在线视频网 | 夜夜操操操操 | 黄色小视频在线免费观看 | 欧美a视频 | 视频一区在线观看 | 亚洲欧美国产另类 | 黄色精品网站 | 日韩视频一区二区三区 | 亚洲一区二区免费看 | 欧美在线a| 日本一级淫片免费看 | 亚洲色综合 | 亚洲国产精品成人 | 久久久久午夜 | av一区二区在线观看 | 日本中文字幕在线观看 | 久久久精品欧美 | 中文字幕av网 | 国产高清视频在线观看 | 亚洲高清资源 | 91电影在线观看 | 久久久网 | 亚洲一区二区三区中文字幕 | 最近免费中文字幕大全免费版视频 | 天天爱天天操 | 日韩视频一区 | 日韩视频精品在线 | 精品一区二区三区久久 | 2012中文版免费观看 | 午夜一区二区三区 | 国产成人一区二区 | 久久久久久一区二区三区 | 日韩精品一区二区三区 | 久久综合九色综合欧美狠狠 | 欧美国产日韩一区二区三区 | 国产中文字幕一区 | 亚洲精品美女 | 中文字幕欧美日韩 |