EDP .Net開發框架--業務模型

来源:https://www.cnblogs.com/alwaysinsist/p/18190582
-Advertisement-
Play Games

EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...


平臺下載地址:https://gitee.com/alwaysinsist/edp


業務模型概述

業務模型管理中所涉及的業務模型,業務模型的屬性,業務模型的視圖都是可以通過許可權設置來實現數據的行(視圖),列(屬性)許可權管控。業務模型是整個EDP平臺的核心基礎,數據的查詢、新增、修改、刪除、行列許可權都是通過業務模型來實現的。

業務模型管理

按分類管理系統內各個業務模型,對應系統中各個業務對象。

業務模型分類

管理業務模型分類。
image

業務模型

  • 新增業務模型
    image
    image

  • 編輯業務模型
    image
    image
    image

  • 業務模型代碼生成
    image
    image

    表設計文檔模板,可以包含多個表結構設計
    image

業務模型開發

定義業務模型

創建業務模型類,繼承基類ModelPermissionBase。定義好的業務模型可以在上述的業務模型管理功能中進行管理,實現數據行、列許可權的管控。

點擊查看代碼
using System;

namespace School.Model
{    
    using EDP.Common.Model;
    using EDP.Common.Help;

    using EDP.Database;
    using EDP.Framework;

    using EDP.Authentication;    

    /// <summary>
    /// 學生業務對象
    /// </summary>
    [ModelEnitity(TableName = "t_school_student", KeyName = "ID")]
    public class StudentModel: ModelPermissionBase
    {
        /// <summary>
        /// 構造函數
        /// </summary>
        public StudentModel() {
            this.SetDefaultQuerySQL(@"select * 
	from (select a.ID
			,a.Name
			,a.Number
			,a.GenderId
			,a.Age
			,a.Contact
			,a.ContactMobile
			,a.Hobby
			,a.CampusId
			,a.ClassId
			,a.CreateUserId
			,a.CreateUserName
			,a.CreateDepartmentId
			,a.CreateOrganizationId
			,a.CreateTime
			,a.ModifyUserId
			,a.ModifyUserName
			,a.ModifyTime
			,a.Remarks
			,b.Name CampusName
			,c.Name ClassName
			,d.Name SchoolName
			,c.FullCode ClassFullCode
		from t_school_student a
		left join t_sys_organization_unit b on a.CampusId = b.ID
		left join t_sys_organization_unit c on a.ClassId = c.ID
		left join t_sys_organization_unit d on c.FullCode like d.FullCode + '%' and d.Levels = c.Levels - 3) tab");
        }

        #region **----實體屬性---------------------------**
        /// <summary>
        /// 主鍵ID
        /// </summary>
        [ModelEnitity(ColumnName = "ID")]
        public string ID { get; set; }

        /// <summary>
        /// 姓名
        /// </summary>
        [ModelEnitity(ColumnName = "Name", IsRequired = true, MaxLength = 50)]
        public string Name { get; set; }

        /// <summary>
        /// 編號
        /// <summary>
        [ModelEnitity(ColumnName = "Number")]
        public string Number { get; set; }

        /// <summary>
        /// 性別ID
        /// </summary>
        [ModelEnitity(ColumnName = "GenderId", IsRequired = true)]
        public int? GenderId { get; set; }

        /// <summary>
        /// 年齡
        /// </summary>
        [ModelEnitity(ColumnName = "Age", IsRequired = true)]
        public int? Age { get; set; }

        /// <summary>
        /// 聯繫人
        /// </summary>
        [ModelEnitity(ColumnName = "Contact", MaxLength = 50)]
        public string Contact { get; set; }

        /// <summary>
        /// 聯繫人手機
        /// </summary>
        [ModelEnitity(ColumnName = "ContactMobile", Regex = @"^[1]([3-9])[0-9]{9}$")]
        public string ContactMobile { get; set; }

        /// <summary>
        /// 興趣愛好
        /// </summary>
        [ModelEnitity(ColumnName = "Hobby", MaxLength = 500)]
        public string Hobby { get; set; }

        /// <summary>
        /// 校區ID
        /// </summary>
        [ModelEnitity(ColumnName = "CampusId")]
        public string CampusId { get; set; }

        /// <summary>
        /// 班級ID
        /// </summary>
        [ModelEnitity(ColumnName = "ClassId", IsRequired = true)]
        public string ClassId { get; set; }

        /// <summary>
        /// 創建人ID
        /// </summary>
        [ModelEnitity(ColumnName = "CreateUserId")]
        public string CreateUserId { get; set; }

        /// <summary>
        /// 創建人
        /// </summary>
        [ModelEnitity(ColumnName = "CreateUserName")]
        public string CreateUserName { get; set; }

        /// <summary>
        /// 創建部門ID
        /// </summary>
        [ModelEnitity(ColumnName = "CreateDepartmentId")]
        public string CreateDepartmentId { get; set; }

        /// <summary>
        /// 創建機構ID
        /// </summary>
        [ModelEnitity(ColumnName = "CreateOrganizationId")]
        public string CreateOrganizationId { get; set; }

        /// <summary>
        /// 創建時間
        /// </summary>
        [ModelEnitity(ColumnName = "CreateTime")]
        public DateTime? CreateTime { get; set; }

        /// <summary>
        /// 修改人ID
        /// </summary>
        [ModelEnitity(ColumnName = "ModifyUserId")]
        public string ModifyUserId { get; set; }

        /// <summary>
        /// 修改人
        /// </summary>
        [ModelEnitity(ColumnName = "ModifyUserName")]
        public string ModifyUserName { get; set; }

        /// <summary>
        /// 修改時間
        /// </summary>
        [ModelEnitity(ColumnName = "ModifyTime")]
        public DateTime? ModifyTime { get; set; }

        /// <summary>
        /// 備註
        /// </summary>
        [ModelEnitity(ColumnName = "Remarks", MaxLength = 1000)]
        public string Remarks { get; set; }
        #endregion

        #region **----擴展屬性---------------------------**
        /// <summary>
        /// 校區名稱
        /// </summary>
        public string CampusName { get; set; }

        /// <summary>
        /// 學校名稱
        /// </summary>
        public string SchoolName { get; set; }

        /// <summary>
        /// 班級名稱
        /// </summary>
        public string ClassName { get; set; }

        /// <summary>
        /// 性別@readonly
        /// </summary>
        public GenderEnum Gender {
            get {
                GenderEnum ret = GenderEnum.None;
                if (this.GenderId.HasValue) {
                    try { ret = (GenderEnum)this.GenderId; }
                    catch { }
                }
                return ret;
            }
        }

        /// <summary>
        /// 性別顯示@readonly
        /// </summary>
        public string GenderDisplay {
            get {
                return EnumHelp.GetEnumDescription(this.Gender);
            }
        }

        /// <summary>
        /// 班級全編碼
        /// </summary>
        public string ClassFullCode { get; set; }

        /// <summary>
        /// 學校
        /// </summary>
        public Organization.OrganizationModel School { get; set; } = new Organization.OrganizationModel();
        #endregion

        #region **----方法-------------------------------**
        /// <summary>
        /// 創建當前實體對象
        /// </summary>
        /// <param name="db">資料庫介面</param>
        public void Create(IDBInstance db = null) {
            if (string.IsNullOrWhiteSpace(this.ID))
                this.ID = Guid.NewGuid().ToString();

            var loginUser = AuthenticationHelp.GetLoginUser(db);
            if (loginUser != null && loginUser.IsLogin) {
                this.CreateUserId = loginUser.UserInfo.ID;
                this.CreateUserName = loginUser.UserInfo.Name;
                this.CreateDepartmentId = loginUser.UserInfo.DepartmentId;
                this.CreateOrganizationId = loginUser.UserInfo.OrganizationId;
            }

            this.CreateTime = DateTime.Now;
            this.ModifyTime = null;
            this.ModifyUserId = null;
            this.ModifyUserName = null;
        }

        /// <summary>
        /// 修改當前實體對象
        /// </summary>
        /// <param name="db">資料庫介面</param>
        public void Modify(IDBInstance db = null) {
            this.ModifyTime = DateTime.Now;

            var loginUser = AuthenticationHelp.GetLoginUser(db);
            if (loginUser != null && loginUser.IsLogin) {
                this.ModifyUserId = loginUser.UserInfo.ID;
                this.ModifyUserName = loginUser.UserInfo.Name;
            }

            this.ModifyTime = DateTime.Now;
            this.CreateDepartmentId = null;
            this.CreateOrganizationId = null;
            this.CreateTime = null;
            this.CreateUserId = null;
            this.CreateUserName = null;
        }

        /// <summary>
        /// 修改當前實體對象
        /// </summary>
        /// <param name="keyValue">主鍵值</param>
        /// <param name="db">資料庫介面</param>
        public void Modify(string keyValue, IDBInstance db = null) {
            this.ID = keyValue;
            this.Modify(db);
        }
        #endregion
    }
}

image

[ModelEnitity(TableName = "t_school_student", KeyName = "ID")]
TableName:表名
KeyName:主鍵對應的屬性名

[ModelEnitity(ColumnName = "Name", IsRequired = true, MaxLength = 50)]
ColumnName:欄位名稱
IsRequired:是否必須,用於驗證屬性值是否必須有值
MaxLength:最大長度,屬性值的最大長度

[ModelEnitity(ColumnName = "ContactMobile", Regex = @"^[1]([3-9])[0-9]{9}$")]
Regex:正則表達式,用於驗證屬性值格式

點擊查看代碼
/// <summary>
/// 構造函數
/// </summary>
public StudentModel() {
            this.SetDefaultQuerySQL(@"select * 
	from (select a.ID
			,a.Name
			,a.Number
			,a.GenderId
			,a.Age
			,a.Contact
			,a.ContactMobile
			,a.Hobby
			,a.CampusId
			,a.ClassId
			,a.CreateUserId
			,a.CreateUserName
			,a.CreateDepartmentId
			,a.CreateOrganizationId
			,a.CreateTime
			,a.ModifyUserId
			,a.ModifyUserName
			,a.ModifyTime
			,a.Remarks
			,b.Name CampusName
			,c.Name ClassName
			,d.Name SchoolName
			,c.FullCode ClassFullCode
		from t_school_student a
		left join t_sys_organization_unit b on a.CampusId = b.ID
		left join t_sys_organization_unit c on a.ClassId = c.ID
		left join t_sys_organization_unit d on c.FullCode like d.FullCode + '%' and d.Levels = c.Levels - 3) tab");

            //引入命名空間 using EDP.Common;
            //default:註冊表配置中資料庫連接配置所對應的"Key"值
            //若沒有設置連線字串,則取註冊表配置中的預設資料庫連接
            //this.SetConnectionString(Config.Database["default"]); 示例項目使用預設資料庫連接,不需要設置
        }
在構造函數中通過SetDefaultQuerySQL()方法設置預設查詢SQL,通過SetConnectionString()方法設置資料庫連接字元串(若沒設置則取預設資料庫連接字串)。

public string CampusName { get; set; }
擴展屬性是預設查詢SQL中所查詢的非業務模型映射的表中的欄位。

點擊查看代碼
/// <summary>
/// 創建當前實體對象
/// </summary>
/// <param name="db">資料庫介面</param>
public void Create(IDBInstance db = null) {
    if (string.IsNullOrWhiteSpace(this.ID))
        this.ID = Guid.NewGuid().ToString();

    var loginUser = AuthenticationHelp.GetLoginUser(db);
    if (loginUser != null && loginUser.IsLogin) {
        this.CreateUserId = loginUser.UserInfo.ID;
        this.CreateUserName = loginUser.UserInfo.Name;
        this.CreateDepartmentId = loginUser.UserInfo.DepartmentId;
        this.CreateOrganizationId = loginUser.UserInfo.OrganizationId;
    }

    this.CreateTime = DateTime.Now;
    this.ModifyTime = null;
    this.ModifyUserId = null;
    this.ModifyUserName = null;
}

/// <summary>
/// 修改當前實體對象
/// </summary>
/// <param name="db">資料庫介面</param>
public void Modify(IDBInstance db = null) {
    this.ModifyTime = DateTime.Now;

    var loginUser = AuthenticationHelp.GetLoginUser(db);
    if (loginUser != null && loginUser.IsLogin) {
        this.ModifyUserId = loginUser.UserInfo.ID;
        this.ModifyUserName = loginUser.UserInfo.Name;
    }

    this.ModifyTime = DateTime.Now;
    this.CreateDepartmentId = null;
    this.CreateOrganizationId = null;
    this.CreateTime = null;
    this.CreateUserId = null;
    this.CreateUserName = null;
}

/// <summary>
/// 修改當前實體對象
/// </summary>
/// <param name="keyValue">主鍵值</param>
/// <param name="db">資料庫介面</param>
public void Modify(string keyValue, IDBInstance db = null) {
    this.ID = keyValue;
    this.Modify(db);
}
在業務對象上提供Create()和Modify()擴展方法,用於在創建和修改業務時調用,給業務對象必要屬性賦值。

定義查詢對象

查詢對象是用來實現業務對象的查詢,通過屬性來設置查詢條件。需要繼承QueryModelBase基類。

點擊查看代碼
using System;

namespace School.Model
{
    using EDP.Common;
    using EDP.Common.Model;

    /// <summary>
    /// 學生信息查詢對象
    /// </summary>
    [QueryModel] //標記類的查詢對象特性
    public class StudentQueryModel : QueryModelBase //繼承QueryModelBase
    {
        /// <summary>
        /// 姓名
        /// </summary>
        [QueryModel(Operator = QueryOperator.like, ColumnName = "Name")]
        public string Name { get; set; }

        /// <summary>
        /// 性別
        /// </summary>
        [QueryModel(Operator = QueryOperator.eq, ColumnName = "GenderId")]
        public int? GenderId { get; set; }

        /// <summary>
        /// 校區
        /// </summary>
        [QueryModel(Operator = QueryOperator.eq, ColumnName = "CampusId")]
        public string CampusId { get; set; }

        /// <summary>
        /// 班級
        /// </summary>
        [QueryModel(Operator = QueryOperator.eq, ColumnName = "ClassId")]
        public string ClassId { get; set; }

        /// <summary>
        /// 班級全編碼
        /// </summary>
        /// <example>ClassFullCode like '值%'</example>
        [QueryModel(Operator = QueryOperator.likeRight, ColumnName = "ClassFullCode")]
        public string ClassFullCode { get; set; }

        /// <summary>
        /// 編號姓名關鍵字
        /// Number和Name都進行like查詢
        /// </summary>
        /// <example>Number like '%關鍵字%' or Name like '%值%'</example>
        [QueryModel(Operator = QueryOperator.like, ColumnNameList = "Number;Name")]
        public string NumberNameKeywrod { get; set; }

        /// <summary>
        /// 分頁對象
        /// </summary>
        public PageModel Page { get; set; } = new PageModel();
    }
}

[QueryModel(Operator = QueryOperator.like, ColumnName = "Name")]
Operator:查詢操作符(=、>、<、>=、like等)
ColumnName:對應業務對象的屬性(實體屬性,擴展屬性),只要是預設查詢SQL中包含的欄位都可以作為查詢對象的屬性(查詢條件)

業務模型使用

詳見示例項目StudentBLL.cs

  • 業務模型屬性驗證
    var verify = item.Verify(keyValue);
    此處通過Verify()方法驗證業務模型各屬性值,通過屬性驗證標記(IsRequired,MaxLength, Regex)進行驗證。

  • 業務模型新增

點擊查看代碼
item.Create(db);
item.ValidateSQL = string.Format("where not exists (select 1 from t_school_student where Number = '{0}')", item.Number);
result = item.InsertModel(db);
通過業務模型Create()方法創建當前實體對象。
通過ValidateSQL屬性值確保不會有重覆的Number值插入到資料庫。
調用InsertModel()方法新增業務模型數據。
  • 修改業務模型
點擊查看代碼
item.Modify(keyValue, db);
item.Number = null; //編號不能修改
result = item.UpdateModel(db);
通過業務模型Modify()方法修改當前實體對象。
調用UpdateModel()方法修改業務模型數據。
  • 業務模型查詢
點擊查看代碼
ResultModel<StudentModel> ret = new ResultModel<StudentModel>();
ret.Content = new StudentModel();
ret.KeyValue = keyValue;
ret.Content.ID = keyValue;
ret.Content.Query(db);
使用統一的返回對象 ResultModel<StudentModel>。
實例化ret.Content並設置操作的主鍵值ret.KeyValue = keyValue。
設置查詢的主鍵值 ret.Content.ID = keyValue。
調用業務對象Query()方法 ret.Content.Query(db)。
執行Query()查詢後,根據許可權設置給ret.Content賦值。
ret.Content.AccessPropertyList中返回有許可權的屬性名稱。
  • 業務模型列表查詢
點擊查看代碼
ResultModel<List<StudentModel>> ret = new ResultModel<List<StudentModel>>();
ret.Content = new List<StudentModel>();
ret.Content.Query(queryModel.Page, queryModel, db);
ret.Page = queryModel.Page;
使用統一的返回對象 ResultModel<List<StudentModel>>。
實例化 ret.Content = new List<StudentModel>()。
調用業務對象Query()方法 ret.Content.Query(queryModel.Page, queryModel, db)。
queryModel為查詢對象StudentQueryModel的實例。
執行Query()查詢後,根據許可權設置給ret.Content賦值(有許可權的數據集合)。
ret.Content[0].AccessPropertyList中返回有許可權的屬性名稱。
  • 業務模型刪除
點擊查看代碼
StudentModel item = new StudentModel();
item.Id = keyValue;
item.DeleteModel();
實例化StudentModel。
設置主鍵值 item.Id = keyValue。
調用業務對象DeleteModel()方法 item.DeleteModel()。

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • EasyBlog 說明 本博客系統通過構建工具生成純靜態的博客網站,藉助GitHub Pages,你可以在5分鐘內免費擁有個人博客。 它具有以下特點 生成純靜態網站,訪問速度極快 使用markdown格式來編寫博客內容 基於git代碼管理來存儲你的博客 使用CI工具來自動化部署你的博客站點 效果展示 ...
  • 開始做項目管理了(本人3年java,來到這邊之後真沒想到...),天天開會溝通整理需求,他們講話的時候忙裡偷閑整理一下常用的方法,其實語言還是有共通性的,基本上看到方法名就大概能猜出來用法。出去打水的時候看到外面太陽好好,真想在外面坐著曬太陽,回來的時候好兄弟三年前送給我的鍵盤D鍵不靈了,在打"等待 ...
  • 一:背景 1. 講故事 停了一個月沒有更新文章了,主要是忙於寫 C#內功修煉系列的PPT,現在基本上接近尾聲,可以回頭繼續更新這段時間分析dump的一些事故報告,有朋友微信上找到我,說他們的系統出現了大量的http超時,程式不響應處理了,讓我幫忙看下怎麼回事,dump也抓到了。 二:WinDbg分析 ...
  • 一、ReZero簡介 ReZero是一款.NET中間件 : 全網唯一開源界面操作就能生成API , 可以集成到任何.NET6+ API項目,無破壞性,也可讓非.NET用戶使用exe文件 免費開源:MIT最寬鬆協議 , 一直從事開源事業十年,一直堅持開源 1.1 純ReZero開發 適合.Net Co ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • 前言 Spacesniffer 是一個免費的文件掃描工具,通過使用樹狀圖可視化佈局,可以立即瞭解大文件夾的位置,幫助用戶處理找到這些文件夾 當前系統C盤空間 清理後系統C盤空間 下載 Spacesniffer 下載地址:https://spacesniffer.en.softonic.com/dow ...
  • efcore如何優雅的實現按年分庫按月分表 介紹 本文ShardinfCore版本 本期主角: ShardingCore 一款ef-core下高性能、輕量級針對分表分庫讀寫分離的解決方案,具有零依賴、零學習成本、零業務代碼入侵適配 距離上次發文.net相關的已經有很久了,期間一直在從事java相關的 ...
  • Channel 是乾什麼的 The System.Threading.Channels namespace provides a set of synchronization data structures for passing data between producers and consume ...
一周排行
    -Advertisement-
    Play Games
  • 前言 微服務架構已經成為搭建高效、可擴展系統的關鍵技術之一,然而,現有許多微服務框架往往過於複雜,使得我們普通開發者難以快速上手並體驗到微服務帶了的便利。為瞭解決這一問題,於是作者精心打造了一款最接地氣的 .NET 微服務框架,幫助我們輕鬆構建和管理微服務應用。 本框架不僅支持 Consul 服務註 ...
  • 先看一下效果吧: 如果不會寫動畫或者懶得寫動畫,就直接交給Blend來做吧; 其實Blend操作起來很簡單,有點類似於在操作PS,我們只需要設置關鍵幀,滑鼠點來點去就可以了,Blend會自動幫我們生成我們想要的動畫效果. 第一步:要創建一個空的WPF項目 第二步:右鍵我們的項目,在最下方有一個,在B ...
  • Prism:框架介紹與安裝 什麼是Prism? Prism是一個用於在 WPF、Xamarin Form、Uno 平臺和 WinUI 中構建鬆散耦合、可維護和可測試的 XAML 應用程式框架 Github https://github.com/PrismLibrary/Prism NuGet htt ...
  • 在WPF中,屏幕上的所有內容,都是通過畫筆(Brush)畫上去的。如按鈕的背景色,邊框,文本框的前景和形狀填充。藉助畫筆,可以繪製頁面上的所有UI對象。不同畫筆具有不同類型的輸出( 如:某些畫筆使用純色繪製區域,其他畫筆使用漸變、圖案、圖像或繪圖)。 ...
  • 前言 嗨,大家好!推薦一個基於 .NET 8 的高併發微服務電商系統,涵蓋了商品、訂單、會員、服務、財務等50多種實用功能。 項目不僅使用了 .NET 8 的最新特性,還集成了AutoFac、DotLiquid、HangFire、Nlog、Jwt、LayUIAdmin、SqlSugar、MySQL、 ...
  • 本文主要介紹攝像頭(相機)如何採集數據,用於類似攝像頭本地顯示軟體,以及流媒體數據傳輸場景如傳屏、視訊會議等。 攝像頭採集有多種方案,如AForge.NET、WPFMediaKit、OpenCvSharp、EmguCv、DirectShow.NET、MediaCaptre(UWP),網上一些文章以及 ...
  • 前言 Seal-Report 是一款.NET 開源報表工具,擁有 1.4K Star。它提供了一個完整的框架,使用 C# 編寫,最新的版本採用的是 .NET 8.0 。 它能夠高效地從各種資料庫或 NoSQL 數據源生成日常報表,並支持執行複雜的報表任務。 其簡單易用的安裝過程和直觀的設計界面,我們 ...
  • 背景需求: 系統需要對接到XXX官方的API,但因此官方對接以及管理都十分嚴格。而本人部門的系統中包含諸多子系統,系統間為了穩定,程式間多數固定Token+特殊驗證進行調用,且後期還要提供給其他兄弟部門系統共同調用。 原則上:每套系統都必須單獨接入到官方,但官方的接入複雜,還要官方指定機構認證的證書 ...
  • 本文介紹下電腦設備關機的情況下如何通過網路喚醒設備,之前電源S狀態 電腦Power電源狀態- 唐宋元明清2188 - 博客園 (cnblogs.com) 有介紹過遠程喚醒設備,後面這倆天瞭解多了點所以單獨加個隨筆 設備關機的情況下,使用網路喚醒的前提條件: 1. 被喚醒設備需要支持這WakeOnL ...
  • 前言 大家好,推薦一個.NET 8.0 為核心,結合前端 Vue 框架,實現了前後端完全分離的設計理念。它不僅提供了強大的基礎功能支持,如許可權管理、代碼生成器等,還通過採用主流技術和最佳實踐,顯著降低了開發難度,加快了項目交付速度。 如果你需要一個高效的開發解決方案,本框架能幫助大家輕鬆應對挑戰,實 ...