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
  • 最近做項目過程中,使用到了海康相機,官方只提供了C/C++的SDK,沒有搜尋到一個合適的封裝了的C#庫,故自己動手,簡單的封裝了一下,方便大家也方便自己使用和二次開發 ...
  • 前言 MediatR 是 .NET 下的一個實現消息傳遞的庫,輕量級、簡潔高效,用於實現進程內的消息傳遞機制。它基於中介者設計模式,支持請求/響應、命令、查詢、通知和事件等多種消息傳遞模式。通過泛型支持,MediatR 可以智能地調度不同類型的消息,非常適合用於領域事件處理。 在本文中,將通過一個簡 ...
  • 前言 今天給大家推薦一個超實用的開源項目《.NET 7 + Vue 許可權管理系統 小白快速上手》,DncZeus的願景就是做一個.NET 領域小白也能上手的簡易、通用的後臺許可權管理模板系統基礎框架。 不管你是技術小白還是技術大佬或者是不懂前端Vue 的新手,這個項目可以快速上手讓我們從0到1,搭建自 ...
  • 第1章:WPF概述 本章目標 瞭解Windows圖形演化 瞭解WPF高級API 瞭解解析度無關性概念 瞭解WPF體繫結構 瞭解WPF 4.5 WPF概述 ​ 歡迎使用 Windows Presentation Foundation (WPF) 桌面指南,這是一個與解析度無關的 UI 框架,使用基於矢 ...
  • 在日常開發中,並不是所有的功能都是用戶可見的,還在一些背後默默支持的程式,這些程式通常以服務的形式出現,統稱為輔助角色服務。今天以一個簡單的小例子,簡述基於.NET開發輔助角色服務的相關內容,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 第3章:佈局 本章目標 理解佈局的原則 理解佈局的過程 理解佈局的容器 掌握各類佈局容器的運用 理解 WPF 中的佈局 WPF 佈局原則 ​ WPF 視窗只能包含單個元素。為在WPF 視窗中放置多個元素並創建更貼近實用的用戶男面,需要在視窗上放置一個容器,然後在這個容器中添加其他元素。造成這一限制的 ...
  • 前言 在平時項目開發中,定時任務調度是一項重要的功能,廣泛應用於後臺作業、計劃任務和自動化腳本等模塊。 FreeScheduler 是一款輕量級且功能強大的定時任務調度庫,它支持臨時的延時任務和重覆迴圈任務(可持久化),能夠按秒、每天/每周/每月固定時間或自定義間隔執行(CRON 表達式)。 此外 ...
  • 目錄Blazor 組件基礎路由導航參數組件參數路由參數生命周期事件狀態更改組件事件 Blazor 組件 基礎 新建一個項目命名為 MyComponents ,項目模板的交互類型選 Auto ,其它保持預設選項: 客戶端組件 (Auto/WebAssembly): 最終解決方案裡面會有兩個項目:伺服器 ...
  • 先看一下效果吧: isChecked = false 的時候的效果 isChecked = true 的時候的效果 然後我們來實現一下這個效果吧 第一步:創建一個空的wpf項目; 第二步:在項目裡面添加一個checkbox <Grid> <CheckBox HorizontalAlignment=" ...
  • 在編寫上位機軟體時,需要經常處理命令拼接與其他設備進行通信,通常對不同的命令封裝成不同的方法,擴展稍許麻煩。 本次擬以特性方式實現,以兼顧維護性與擴展性。 思想: 一種命令對應一個類,其類中的各個屬性對應各個命令段,通過特性的方式,實現其在這包數據命令中的位置、大端或小端及其轉換為對應的目標類型; ...