1. 程式人生 > >OsharpNS輕量級.net core快速開發框架簡明入門教程-基於Osharp實現自己的業務功能

OsharpNS輕量級.net core快速開發框架簡明入門教程-基於Osharp實現自己的業務功能

bapi creat 建議 存儲對象 required arc space 學習 category

OsharpNS輕量級.net core快速開發框架簡明入門教程

教程目錄

  1. 從零開始啟動Osharp

    1.1. 使用OsharpNS項目模板創建項目

    1.2. 配置數據庫連接串並啟動項目

    1.3. OsharpNS.Swagger使用實例(登錄和授權)

    1.4. Angular6的前端項目啟動

  2. Osharp代碼生成器的使用

    2.1 生成器的使用

    2.2 生成代碼詳解(如何自己實現業務功能)

  3. Osharp部分模塊使用

    3.1 Osharp.Redis使用

    3.2 Osharp.Hangfire使用

    3.3 Osharp.Permissions使用

  4. Osharp深度學習和使用

    4.1 切換數據庫(從SqlServer改為MySql)

    4.2 多上下文配置(多個數據庫的使用)

    4.3. 自定義模塊的定義(Senparc.Weixin的使用)

    4.4. 繼續學習中....

OsharpNS官方資源
項目地址:https://github.com/i66soft/osharp-ns20
演示地址:https://www.osharp.org 直接使用QQ登錄可以查看效果
文檔地址:https://docs.osharp.org 正在完善中....
發布博客:https://www.cnblogs.com/guomingfeng/p/osharpns-publish.html 大神看這個文檔應該就能跑起來,從零開始啟動Osharp基於此文檔完成
VS生成器插件:https://marketplace.visualstudio.com/items?itemName=LiuliuSoft.osharp

官方交流QQ群:85895249

基於Osharp實現自己的業務功能

目錄

  1. 基於Osharp實現業務的編碼流程

  2. Core模塊代碼

  3. EntityConfiguration模塊代碼

  4. WebApi模塊代碼

基於Osharp實現業務的編碼流程

本篇基於教程前面的項目和生成的代碼展開,CanDoo.Test是使用項目模板創建的項目命名空間,CMS是使用生成器創建的內容管理模塊,如不明白,請看前面的教程。

  1. 根據業務需求,確定需要開發的模塊,和各個模塊需要的實體及實體屬性

  2. 根據業務需要分模塊定義實體屬性,位於CanDoo.Test.Core/CMS/Entities

  3. 根據實體的定義,完成實體各屬性的數據庫配置,位於CanDoo.Test.EntityConfiguration/CMS/

  4. 根據業務需要定義輸入、輸出Dto,位於CanDoo.Test.Core/CMS/Dtos

  5. 根據業務需要定義此實體對應的功能接口,位於CanDoo.Test.Core/CMS

  6. 根據業務需求實現功能,位於CanDoo.Test.Core/CMS

  7. 新建一個自定義模塊,完成接口和服務的依賴註入,位於CanDoo.Test.Core/CMS

  8. 新建一個控制器,調用對應模塊的接口,定義對應功能的WebApi,前端調用WebApi完成用戶界面,位於CanDoo.Test.Web/Areas/Admin/Controllers/CMS

  9. 下圖為接下去講解代碼在項目中的位置,很多文件以.generated.cs,此文件為代碼自動生成的模板代碼,實現了基礎的增刪改查操作,當使用生成器重新生成代碼時,此文件會被覆蓋,如果實現代碼需要改動,不建議直接在此文件上改動,建議新建一個文件,繼承自以.generated.cs結尾的文件,在新文件中改動相關的實現,從而避免重新生成代碼,導致自定義代碼被覆蓋

    技術分享圖片

    技術分享圖片

Core模塊代碼

接下去以CMS模塊中的Article為了來講解相關代碼

  1. 實體的定義:

    EntityBase:定義了主鍵Id的類型為int

    ILockable:定義可鎖定功能,需定義屬性:IsLocked

    ISoftDeletable:定義邏輯刪除功能,需定義屬性:DeletedTime

    ICreationAudited:定義創建審計信息,需定義屬性:CreatorId,CreatedTime

    IUpdateAudited:定義更新審計信息,需定義屬性:LastUpdaterId,LastUpdatedTime

    //------------------------------------------------------------------------------
    // <auto-generated>
    //    此代碼由代碼生成器生成。
    //    手動更改此文件可能導致應用程序出現意外的行為。
    //    如果重新生成代碼,對此文件的任何修改都會丟失。
    //    如果需要擴展此類,請新建分部類 partial class Article 進行擴展
    // </auto-generated>
    //
    //  <copyright file="Article.generated.cs" company="杭州乾渡科技有限公司">
    //      Copyright  2019 乾渡科技出品
    //  </copyright>
    //  <site>https://www.osharp.org</site>
    //  <last-editor>atai</last-editor>
    //  <last-date>2019-04-27 10:04</last-date>
    // -----------------------------------------------------------------------
    
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    
    using OSharp.Entity;
    
    using CanDoo.Test.Identity.Entities;
    
    namespace CanDoo.Test.CMS.Entities
    
    {
    
        /// <summary>
        /// 實體類:文章信息
        /// </summary>
        [Description("文章信息")]
        public partial class Article : EntityBase<int>, ILockable, ISoftDeletable, ICreationAudited<int>, IUpdateAudited<int>
        {
            /// <summary>
            /// 獲取或設置 標題
            /// </summary>
            [DisplayName("標題")]
            public string Title { get; set; }
    
            /// <summary>
            /// 獲取或設置 內容
            /// </summary>
            [DisplayName("內容")]
            public string Content { get; set; }
    
            /// <summary>
            /// 獲取或設置 是否鎖定
            /// </summary>
            [DisplayName("是否鎖定")]
            public bool IsLocked { get; set; }
    
            /// <summary>
            /// 獲取或設置 刪除時間
            /// </summary>
            [DisplayName("刪除時間")]
            public DateTime? DeletedTime { get; set; }
    
            /// <summary>
            /// 獲取或設置 創建者
            /// </summary>
            [DisplayName("創建者")]
            public int? CreatorId { get; set; }
    
            /// <summary>
            /// 獲取或設置 創建時間
            /// </summary>
            [DisplayName("創建時間")]
            public DateTime CreatedTime { get; set; }
    
            /// <summary>
            /// 獲取或設置 更新者
            /// </summary>
            [DisplayName("更新者")]
            public int? LastUpdaterId { get; set; }
    
            /// <summary>
            /// 獲取或設置 更新時間
            /// </summary>
            [DisplayName("更新時間")]
            public DateTime? LastUpdatedTime { get; set; }
    
            /// <summary>
            /// 獲取或設置 分類外鍵
            /// </summary>
            [DisplayName("分類外鍵")]
            public int ArticleCategoryId { get; set; }
    
            /// <summary>
            /// 獲取或設置 發布人外鍵
            /// </summary>
            [DisplayName("發布人外鍵")]
            public int? UserId { get; set; }
    
            /// <summary>
            /// 獲取或設置 分類
            /// </summary>
            [DisplayName("分類")]
            public virtual ArticleCategory ArticleCategory { get; set; }
    
            /// <summary>
            /// 獲取或設置 發布人
            /// </summary>
            [DisplayName("發布人")]
            public virtual User User { get; set; }
    
        }
    
    }
  2. InputDto的定義:此Dto用於向系統輸入數據的時候,比如新增數據,編輯數據時,通過InputDto來提供數據

    IInputDto:定義了主鍵類型為int

    
    // -----------------------------------------------------------------------
    // <auto-generated>
    //    此代碼由代碼生成器生成。
    //    手動更改此文件可能導致應用程序出現意外的行為。
    //    如果重新生成代碼,對此文件的任何修改都會丟失。
    //    如果需要擴展此類,請新建分部類 partial class ArticleInputDto 進行擴展
    // </auto-generated>
    //
    //  <copyright file="ArticleInputDto.generated.cs" company="杭州乾渡科技有限公司">
    //      Copyright  2019 乾渡科技出品
    //  </copyright>
    //  <site>https://www.osharp.org</site>
    //  <last-editor>atai</last-editor>
    //  <last-date>2019-04-27 10:04</last-date>
    // -----------------------------------------------------------------------
    
    using System;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    
    using OSharp.Entity;
    using OSharp.Mapping;
    
    using CanDoo.Test.CMS.Entities;
    
    namespace CanDoo.Test.CMS.Dtos
    {
        /// <summary>
        /// 輸入DTO:文章信息
        /// </summary>
        [MapTo(typeof(Article))]
        [Description("文章信息")]
        public partial class ArticleInputDto : IInputDto<int>
        {
            /// <summary>
            /// 獲取或設置 編號
            /// </summary>
            [DisplayName("編號")]
            public int Id { get; set; }
    
            /// <summary>
            /// 獲取或設置 分類外鍵
            /// </summary>
            [DisplayName("分類外鍵")]
            public int ArticleCategoryId { get; set; }
    
            /// <summary>
            /// 獲取或設置 標題
            /// </summary>
            [DisplayName("標題")]
            public string Title { get; set; }
    
            /// <summary>
            /// 獲取或設置 內容
            /// </summary>
            [DisplayName("內容")]
            public string Content { get; set; }
    
            /// <summary>
            /// 獲取或設置 發布人外鍵
            /// </summary>
            [DisplayName("發布人外鍵")]
            public int UserId { get; set; }
    
            /// <summary>
            /// 獲取或設置 是否鎖定
            /// </summary>
            [DisplayName("是否鎖定")]
            public bool IsLocked { get; set; }
    
        }
    
    }
  3. OutDto的定義:此Dto用於輸出數據給用戶時候,比如數據列表展示,展示數據詳情的時候,通過OutDto來提供數據

    IDataAuthEnabled:定義數據權限的允許更新,允許刪除狀態,需定義:Updatable,Deletable

    // -----------------------------------------------------------------------
    // <auto-generated>
    //    此代碼由代碼生成器生成。
    //    手動更改此文件可能導致應用程序出現意外的行為。
    //    如果重新生成代碼,對此文件的任何修改都會丟失。
    //    如果需要擴展此類,請新建分部類 partial class ArticleOutputDto 進行擴展
    // </auto-generated>
    //
    //  <copyright file="ArticleOutputDto.generated.cs" company="杭州乾渡科技有限公司">
    //      Copyright  2019 乾渡科技出品
    //  </copyright>
    //  <site>https://www.osharp.org</site>
    //  <last-editor>atai</last-editor>
    //  <last-date>2019-04-27 10:04</last-date>
    // -----------------------------------------------------------------------
    
    using System;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    
    using OSharp.Entity;
    using OSharp.Mapping;
    
    using CanDoo.Test.CMS.Entities;
    using CanDoo.Test.Identity.Entities;
    
    namespace CanDoo.Test.CMS.Dtos
    {
        /// <summary>
        /// 輸入DTO:文章信息
        /// </summary>
        [MapFrom(typeof(Article))]
        [Description("文章信息")]
        public partial class ArticleOutputDto : IOutputDto, IDataAuthEnabled
        {
            /// <summary>
            /// 獲取或設置 編號
            /// </summary>
            [DisplayName("編號")]
            public int Id { get; set; }
    
            /// <summary>
            /// 獲取或設置 分類
            /// </summary>
            [DisplayName("分類")]
            public ArticleCategory ArticleCategory { get; set; }
    
            /// <summary>
            /// 獲取或設置 標題
            /// </summary>
            [DisplayName("標題")]
            public string Title { get; set; }
    
            /// <summary>
            /// 獲取或設置 內容
            /// </summary>
            [DisplayName("內容")]
            public string Content { get; set; }
    
            /// <summary>
            /// 獲取或設置 發布人
            /// </summary>
            [DisplayName("發布人")]
            public User User { get; set; }
    
            /// <summary>
            /// 獲取或設置 是否鎖定
            /// </summary>
            [DisplayName("是否鎖定")]
            public bool IsLocked { get; set; }
    
            /// <summary>
            /// 獲取或設置 創建者
            /// </summary>
            [DisplayName("創建者")]
            public int CreatorId { get; set; }
    
            /// <summary>
            /// 獲取或設置 創建時間
            /// </summary>
            [DisplayName("創建時間")]
            public DateTime CreatedTime { get; set; }
    
            /// <summary>
            /// 獲取或設置 更新者
            /// </summary>
            [DisplayName("更新者")]
            public int LastUpdaterId { get; set; }
    
            /// <summary>
            /// 獲取或設置 更新時間
            /// </summary>
            [DisplayName("更新時間")]
            public DateTime LastUpdatedTime { get; set; }
    
            /// <summary>
            /// 獲取或設置 是否可更新的數據權限狀態
            /// </summary>
            public bool Updatable { get; set; }
    
            /// <summary>
            /// 獲取或設置 是否可刪除的數據權限狀態
            /// </summary>
            public bool Deletable { get; set; }
    
        }
    
    }
  4. 接口的定義:定義需要的接口

    // -----------------------------------------------------------------------
    // <auto-generated>
    //    此代碼由代碼生成器生成。
    //    手動更改此文件可能導致應用程序出現意外的行為。
    //    如果重新生成代碼,對此文件的任何修改都會丟失。
    //    如果需要擴展此接口,請新建分部接口 partial interface ICMSContract 添加新的方法,並添加相應新的分部基類 abstract partial class CMSServiceBase 實現新方法
    // </auto-generated>
    //
    //  <copyright file="ICMSContract.generated.cs" company="杭州乾渡科技有限公司">
    //      Copyright  2019 乾渡科技出品
    //  </copyright>
    //  <site>https://www.osharp.org</site>
    //  <last-editor>atai</last-editor>
    //  <last-date>2019-04-27 10:04</last-date>
    // -----------------------------------------------------------------------
    
    using System;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Threading.Tasks;
    
    using OSharp.Data;
    using OSharp.Extensions;
    
    using CanDoo.Test.CMS.Dtos;
    using CanDoo.Test.CMS.Entities;
    
    namespace CanDoo.Test.CMS
    {
        /// <summary>
        /// 業務契約接口:內容管理模塊
        /// </summary>
        public partial interface ICMSContract
        {
    
            #region 文章分類信息業務
    
            #endregion
    
            #region 文章信息業務
    
            /// <summary>
            /// 獲取 文章信息查詢數據集
            /// </summary>
            IQueryable<Article> Articles { get; }
    
            /// <summary>
            /// 檢查文章信息信息是否存在
            /// </summary>
            /// <param name="predicate">檢查謂語表達式</param>
            /// <param name="id">更新的文章信息編號</param>
            /// <returns>文章信息是否存在</returns>
            Task<bool> CheckArticleExists(Expression<Func<Article, bool>> predicate, int id = default(int));
    
            /// <summary>
            /// 添加文章信息信息
            /// </summary>
            /// <param name="dtos">要添加的文章信息DTO信息</param>
            /// <returns>業務操作結果</returns>
            Task<OperationResult> CreateArticles(params ArticleInputDto[] dtos);
    
            /// <summary>
            /// 更新文章信息信息
            /// </summary>
            /// <param name="dtos">包含更新信息的文章信息DTO信息</param>
            /// <returns>業務操作結果</returns>
            Task<OperationResult> UpdateArticles(params ArticleInputDto[] dtos);
    
            /// <summary>
            /// 刪除文章信息信息
            /// </summary>
            /// <param name="ids">要刪除的文章信息編號</param>
            /// <returns>業務操作結果</returns>
            Task<OperationResult> DeleteArticles(params int[] ids);
    
            #endregion
    
            #region 留言板信息業務
    
            #endregion
    
        }
    
    }
  5. 功能實現:因為一個功能模塊中會有大量的實體,系統中將各個實體的具體實現進行了文件的拆分,從前面的圖中可以看出,Article的具體實現位於CMSServiceBase.Article.generated.csCMSServiceBase.generated.cs定義了CMS模塊所有需要使用到的對象,CMSService.cs為模塊的業務實現基類

   // -----------------------------------------------------------------------
   // <auto-generated>
   //    此代碼由代碼生成器生成。
   //    手動更改此文件可能導致應用程序出現意外的行為。
   //    如果重新生成代碼,對此文件的任何修改都會丟失。
   //    如果需要擴展此類,可以遵守如下規則進行擴展:
   //      1.橫向擴展:如需給當前實體 Article 添加方法,可新建文件“CMSServiceBase.Article.cs”的分部類“public abstract partial class CMSServiceBase”添加功能
   //      2.縱向擴展:如需要重寫當前實體 Article 的業務實現,可新建文件“CMSService.Article.cs”的分部類“public partial class CMSService”對現有方法進行方法重寫實現
   // </auto-generated>
   //
   //  <copyright file="CMSServiceBase.Article.generated.cs" company="杭州乾渡科技有限公司">
   //      Copyright  2019 乾渡科技出品
   //  </copyright>
   //  <site>https://www.osharp.org</site>
   //  <last-editor>atai</last-editor>
   //  <last-date>2019-04-27 10:04</last-date>
   // -----------------------------------------------------------------------

   using System;
   using System.Linq;
   using System.Linq.Expressions;
   using System.Threading.Tasks;

   using OSharp.Data;
   using OSharp.Dependency;
   using OSharp.Extensions;
   using OSharp.Mapping;

   using CanDoo.Test.CMS.Dtos;
   using CanDoo.Test.CMS.Entities;

   namespace CanDoo.Test.CMS
   {
       public abstract partial class CMSServiceBase
       {
           /// <summary>
           /// 獲取 文章信息查詢數據集
           /// </summary>
           public IQueryable<Article> Articles
           {
               get { return ArticleRepository.Query(); }
           }

           /// <summary>
           /// 檢查文章信息是否存在
           /// </summary>
           /// <param name="predicate">檢查謂語表達式</param>
           /// <param name="id">更新的文章信息編號</param>
           /// <returns>文章信息是否存在</returns>
           public virtual Task<bool> CheckArticleExists(Expression<Func<Article, bool>> predicate, int id = default(int))
           {
               return ArticleRepository.CheckExistsAsync(predicate, id);
           }
    
           /// <summary>
           /// 添加文章信息
           /// </summary>
           /// <param name="dtos">要添加的文章信息DTO信息</param>
           /// <returns>業務操作結果</returns>
           public virtual Task<OperationResult> CreateArticles(params ArticleInputDto[] dtos)
           {
               Check.NotNull(dtos, nameof(dtos));
               return ArticleRepository.InsertAsync(dtos);
           }
    
           /// <summary>
           /// 更新文章信息
           /// </summary>
           /// <param name="dtos">包含更新信息的文章信息DTO信息</param>
           /// <returns>業務操作結果</returns>
           public virtual Task<OperationResult> UpdateArticles(params ArticleInputDto[] dtos)
           {
               Check.NotNull(dtos, nameof(dtos));
               return ArticleRepository.UpdateAsync(dtos);
           }
    
           /// <summary>
           /// 刪除文章信息
           /// </summary>
           /// <param name="ids">要刪除的文章信息編號</param>
           /// <returns>業務操作結果</returns>
           public virtual Task<OperationResult> DeleteArticles(params int[] ids)
           {
               Check.NotNull(ids, nameof(ids));
               return ArticleRepository.DeleteAsync(ids);
           }
       }

   }

   // -----------------------------------------------------------------------
   // <auto-generated>
   //    此代碼由代碼生成器生成。
   //    手動更改此文件可能導致應用程序出現意外的行為。
   //    如果重新生成代碼,對此文件的任何修改都會丟失。
   //    如果需要擴展此類,請在控制器類型 CMSService 進行繼承重寫
   // </auto-generated>
   //
   //  <copyright file="ICMSServiceBase.generated.cs" company="杭州乾渡科技有限公司">
   //      Copyright  2019 乾渡科技出品
   //  </copyright>
   //  <site>https://www.osharp.org</site>
   //  <last-editor>atai</last-editor>
   //  <last-date>2019-04-27 10:04</last-date>
   // -----------------------------------------------------------------------

   using System;
   using System.Linq;
   using System.Threading.Tasks;

   using OSharp.Core.Systems;
   using OSharp.Data;
   using OSharp.Entity;
   using OSharp.EventBuses;
   using OSharp.Extensions;
   using OSharp.Identity;

   using Microsoft.Extensions.DependencyInjection;
   using Microsoft.Extensions.Logging;

   using CanDoo.Test.CMS.Dtos;
   using CanDoo.Test.CMS.Entities;

   namespace CanDoo.Test.CMS
   {
       /// <summary>
       /// 業務實現基類:內容管理模塊
       /// </summary>
       public abstract partial class CMSServiceBase : ICMSContract
       {
           /// <summary>
           /// 初始化一個<see cref="CMSService"/>類型的新實例
           /// </summary>
           protected CMSServiceBase(IServiceProvider provider)
           {
               ServiceProvider = provider;
               Logger = provider.GetLogger(GetType());
           }

           #region 屬性
    
           /// <summary>
           /// 獲取或設置 服務提供者對象
           /// </summary>
           protected IServiceProvider ServiceProvider { get; }
    
           /// <summary>
           /// 獲取或設置 日誌對象
           /// </summary>
           protected ILogger Logger { get; }
    
           /// <summary>
           /// 獲取或設置 文章分類信息倉儲對象
           /// </summary>
           protected IRepository<ArticleCategory, int> ArticleCategoryRepository => ServiceProvider.GetService<IRepository<ArticleCategory, int>>();
    
           /// <summary>
           /// 獲取或設置 文章信息倉儲對象
           /// </summary>
           protected IRepository<Article, int> ArticleRepository => ServiceProvider.GetService<IRepository<Article, int>>();
    
           /// <summary>
           /// 獲取或設置 留言板信息倉儲對象
           /// </summary>
           protected IRepository<MessageBoard, int> MessageBoardRepository => ServiceProvider.GetService<IRepository<MessageBoard, int>>();
    
           /// <summary>
           /// 獲取 事件總線
           /// </summary>
           protected IEventBus EventBus => ServiceProvider.GetService<IEventBus>();
    
           /// <summary>
           /// 獲取 設置存儲對象
           /// </summary>
           protected IKeyValueStore KeyValueStore => ServiceProvider.GetService<IKeyValueStore>();
    
           #endregion
       }

   }
   // -----------------------------------------------------------------------
   // <once-generated>
   //     這個文件只生成一次,再次生成不會被覆蓋。
   //     可以在此類進行繼承重寫來擴展基類 CMSServiceBase
   // </once-generated>
   //
   //  <copyright file="ICMSService.cs" company="Qiadoo">
   //      隨便用
   //  </copyright>
   //  <site>http://www.qiadoo.com</site>
   //  <last-editor>atai</last-editor>
   //  <last-date>2019-04-26 13:52</last-date>
   // -----------------------------------------------------------------------

   using System;

   namespace CanDoo.Test.CMS
   {
       /// <summary>
       /// 業務實現基類:內容管理模塊
       /// </summary>
       public partial class CMSService : CMSServiceBase
       {
           /// <summary>
           /// 初始化一個<see cref="CMSService"/>類型的新實例
           /// </summary>
           public CMSService(IServiceProvider provider)
               : base(provider)
           { }
       }
   }
  1. 模塊定義:將模塊服務添加到依賴註入服務容器中

    OsharpPack:系統啟動的時候會自動查找繼承自OsharpPack的模塊,完成加載

    // -----------------------------------------------------------------------
    // <auto-generated>
    //    此代碼由代碼生成器生成。
    //    手動更改此文件可能導致應用程序出現意外的行為。
    //    如果重新生成代碼,對此文件的任何修改都會丟失。
    //    如果需要擴展此類,請新建分部類 partial class CMSPack 進行實現分部方法 AddServicesAppend,UsePackAppend 進行擴展
    // </auto-generated>
    //
    //  <copyright file="ICMSPack.generated.cs" company="杭州乾渡科技有限公司">
    //      Copyright  2019 乾渡科技出品
    //  </copyright>
    //  <site>https://www.osharp.org</site>
    //  <last-editor>atai</last-editor>
    //  <last-date>2019-04-27 10:04</last-date>
    // -----------------------------------------------------------------------
    
    using System;
    using System.ComponentModel;
    
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.DependencyInjection.Extensions;
    
    using OSharp.Core.Packs;
    
    namespace CanDoo.Test.CMS
    {
        /// <summary>
        /// 內容管理模塊
        /// </summary>
        [Description("內容管理模塊")]
        public partial class CMSPack : OsharpPack
        {
            /// <summary>將模塊服務添加到依賴註入服務容器中</summary>
            /// <param name="services">依賴註入服務容器</param>
            /// <returns></returns>
            public override IServiceCollection AddServices(IServiceCollection services)
            {
                services.TryAddScoped<ICMSContract, CMSService>();
                AddServicesAppend(services);
    
                return services;
            }
    
            /// <summary>
            /// 額外的服務註冊
            /// </summary>
            /// <param name="services">依賴註入服務容器</param>
            partial void AddServicesAppend(IServiceCollection services);
    
            /// <summary>
            /// 應用模塊服務
            /// </summary>
            /// <param name="provider">服務提供者</param>
            public override void UsePack(IServiceProvider provider)
            {
                UsePackAppend(provider);
    
                base.UsePack(provider);
            }
    
            /// <summary>
            /// 額外的服務註冊
            /// </summary>
            /// <param name="provider">服務提供者</param>
            partial void UsePackAppend(IServiceProvider provider);
        }
    
    }

EntityConfiguration模塊代碼解析

直接貼代碼了,在這裏完成了各個屬性的數據庫配置,以下2行都是多對一的配置,第一條是文章和文章分類實現雙向導航,第二條是文章和用戶的單向導航,當然在這裏還能指定表的名稱等等,反正數據庫想怎麽配置就在這裏折騰吧

builder.HasOne<ArticleCategory>(m => m.ArticleCategory).WithMany(n => n.Articles).HasForeignKey(m => m.ArticleCategoryId).IsRequired().OnDelete(DeleteBehavior.Restrict);
builder.HasOne<User>(m => m.User).WithMany().HasForeignKey(m => m.UserId).IsRequired().OnDelete(DeleteBehavior.Restrict);
//------------------------------------------------------------------------------
// <auto-generated>
//    此代碼由代碼生成器生成。
//    手動更改此文件可能導致應用程序出現意外的行為。
//    如果重新生成代碼,對此文件的任何修改都會丟失。
//    如果需要擴展此類,請新建分部類 partial class ArticleConfiguration 實現分部方法 EntityConfigurationAppend 進行擴展
// </auto-generated>
//
//  <copyright file="ArticleConfiguration.generated.cs" company="杭州乾渡科技有限公司">
//      Copyright  2019 乾渡科技出品
//  </copyright>
//  <site>https://www.osharp.org</site>
//  <last-editor>atai</last-editor>
//  <last-date>2019-04-27 10:04</last-date>
// -----------------------------------------------------------------------

using System;

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

using OSharp.Entity;

using CanDoo.Test.CMS.Entities;
using CanDoo.Test.Identity.Entities;

namespace CanDoo.Test.EntityConfiguration.CMS
{
    /// <summary>
    /// 實體配置類:文章信息
    /// </summary>
    public partial class ArticleConfiguration : EntityTypeConfigurationBase<Article, int>
    {
        /// <summary>
        /// 重寫以實現實體類型各個屬性的數據庫配置
        /// </summary>
        /// <param name="builder">實體類型創建器</param>
        public override void Configure(EntityTypeBuilder<Article> builder)
        {
            builder.HasOne<ArticleCategory>(m => m.ArticleCategory).WithMany(n => n.Articles).HasForeignKey(m => m.ArticleCategoryId).IsRequired().OnDelete(DeleteBehavior.Restrict);
            builder.HasOne<User>(m => m.User).WithMany().HasForeignKey(m => m.UserId).IsRequired().OnDelete(DeleteBehavior.Restrict);

            EntityConfigurationAppend(builder);
        }
    
        /// <summary>
        /// 額外的數據映射
        /// </summary>
        partial void EntityConfigurationAppend(EntityTypeBuilder<Article> builder);
    }

}

WebApi模塊代碼

還是沒啥說的,自己看代碼吧,註意看下對AdminApiController的繼承,


// -----------------------------------------------------------------------
//  <copyright file="AdminApiController.cs" company="OSharp開源團隊">
//      Copyright (c) 2014-2018 OSharp. All rights reserved.
//  </copyright>
//  <site>http://www.osharp.org</site>
//  <last-editor>郭明鋒</last-editor>
//  <last-date>2018-06-27 4:50</last-date>
// -----------------------------------------------------------------------

using Microsoft.AspNetCore.Mvc;

using OSharp.AspNetCore.Mvc;
using OSharp.Core;

namespace CanDoo.Test.Web.Areas.Admin.Controllers
{
    [Area("Admin")]
    [RoleLimit]//繼承了這個,就會進行權限檢查

    public abstract class AdminApiController : AreaApiController
    { }

}

// -----------------------------------------------------------------------
// <auto-generated>
//    此代碼由代碼生成器生成。
//    手動更改此文件可能導致應用程序出現意外的行為。
//    如果重新生成代碼,對此文件的任何修改都會丟失。
//    如果需要擴展此類,請在控制器類型 ArticleController 進行繼承重寫
// </auto-generated>
//
//  <copyright file="ArticleBase.generated.cs" company="杭州乾渡科技有限公司">
//      Copyright  2019 乾渡科技出品
//  </copyright>
//  <site>https://www.osharp.org</site>
//  <last-editor>atai</last-editor>
//  <last-date>2019-04-27 10:04</last-date>
// -----------------------------------------------------------------------

using System;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

using Microsoft.AspNetCore.Mvc;

using OSharp.AspNetCore.Mvc;
using OSharp.AspNetCore.Mvc.Filters;
using OSharp.AspNetCore.UI;
using OSharp.Caching;
using OSharp.Core.Functions;
using OSharp.Core.Modules;
using OSharp.Data;
using OSharp.Entity;
using OSharp.Filter;
using OSharp.Secutiry;

using CanDoo.Test.CMS;
using CanDoo.Test.CMS.Dtos;
using CanDoo.Test.CMS.Entities;

namespace CanDoo.Test.Web.Areas.Admin.Controllers
{
    /// <summary>
    /// 管理控制器基類: 文章信息
    /// </summary>
    [ModuleInfo(Position = "CMS", PositionName = "內容管理模塊")]
    [Description("管理-文章信息")]
    public abstract class ArticleControllerBase : AdminApiController
    {
        /// <summary>
        /// 初始化一個<see cref="ArticleController"/>類型的新實例
        /// </summary>
        protected ArticleControllerBase(ICMSContract cMSContract,
            IFilterService filterService)
        {
            CMSContract = cMSContract;
            FilterService = filterService;
        }

        /// <summary>
        /// 獲取或設置 數據過濾服務對象
        /// </summary>
        protected IFilterService FilterService { get; }
    
        /// <summary>
        /// 獲取或設置 內容管理模塊業務契約對象
        /// </summary>
        protected ICMSContract CMSContract { get; }
    
        /// <summary>
        /// 讀取文章列表信息
        /// </summary>
        /// <param name="request">頁請求信息</param>
        /// <returns>文章列表分頁信息</returns>
        [HttpPost]
        [ModuleInfo]
        [Description("讀取")]
        public virtual PageData<ArticleOutputDto> Read(PageRequest request)
        {
            Check.NotNull(request, nameof(request));
    
            Expression<Func<Article, bool>> predicate = FilterService.GetExpression<Article>(request.FilterGroup);
            var page = CMSContract.Articles.ToPage<Article, ArticleOutputDto>(predicate, request.PageCondition);
    
            return page.ToPageData();
        }
    
        /// <summary>
        /// 新增文章信息
        /// </summary>
        /// <param name="dtos">文章信息輸入DTO</param>
        /// <returns>JSON操作結果</returns>
        [HttpPost]
        [ModuleInfo]
        [DependOnFunction("Read")]
        [ServiceFilter(typeof(UnitOfWorkAttribute))]
        [Description("新增")]
        public virtual async Task<AjaxResult> Create(ArticleInputDto[] dtos)
        {
            Check.NotNull(dtos, nameof(dtos));
            OperationResult result = await CMSContract.CreateArticles(dtos);
            return result.ToAjaxResult();
        }
    
        /// <summary>
        /// 更新文章信息
        /// </summary>
        /// <param name="dtos">文章信息輸入DTO</param>
        /// <returns>JSON操作結果</returns>
        [HttpPost]
        [ModuleInfo]
        [DependOnFunction("Read")]
        [ServiceFilter(typeof(UnitOfWorkAttribute))]
        [Description("更新")]
        public virtual async Task<AjaxResult> Update(ArticleInputDto[] dtos)
        {
            Check.NotNull(dtos, nameof(dtos));
            OperationResult result = await CMSContract.UpdateArticles(dtos);
            return result.ToAjaxResult();
        }
    
        /// <summary>
        /// 刪除文章信息
        /// </summary>
        /// <param name="ids">文章信息編號</param>
        /// <returns>JSON操作結果</returns>
        [HttpPost]
        [ModuleInfo]
        [DependOnFunction("Read")]
        [ServiceFilter(typeof(UnitOfWorkAttribute))]
        [Description("刪除")]
        public virtual async Task<AjaxResult> Delete(int[] ids)
        {
            Check.NotNull(ids, nameof(ids));
            OperationResult result = await CMSContract.DeleteArticles(ids);
            return result.ToAjaxResult();
        }
    }

}

// -----------------------------------------------------------------------
// <once-generated>
//     這個文件只生成一次,再次生成不會被覆蓋。
//     可以在此類進行繼承重寫來擴展基類 ArticleControllerBase
// </once-generated>
//
//  <copyright file="Article.cs" company="Qiadoo">
//      隨便用
//  </copyright>
//  <site>http://www.qiadoo.com</site>
//  <last-editor>atai</last-editor>
//  <last-date>2019-04-26 13:52</last-date>
// -----------------------------------------------------------------------

using System;

using OSharp.Filter;

using CanDoo.Test.CMS;

namespace CanDoo.Test.Web.Areas.Admin.Controllers
{
    /// <summary>
    /// 管理控制器: 文章信息
    /// </summary>
    public class ArticleController : ArticleControllerBase
    {
        /// <summary>
        /// 初始化一個<see cref="ArticleController"/>類型的新實例
        /// </summary>
        public ArticleController(ICMSContract cMSContract,
            IFilterService filterService)
            : base(cMSContract, filterService)
        { }
    }
}

OsharpNS輕量級.net core快速開發框架簡明入門教程-基於Osharp實現自己的業務功能