這款ORM框架的原版在經歷過大概十幾個項目的磨合,最近整理了一下,原名字為:ZhCun.Framework ,該框架輾轉跟了我去過幾家公司,大概從2012年出現第一個版本,當時就為簡化數據庫操作,從優化SQLHelper,代碼生成器,一直到今天個人感覺還算好用的框架;
剛開始寫完它的時候是因為當時公司的框架實在太難用(好像是實體為強類型DataTable,實體類太過笨重),但公司因為人員維護及其它的綜合考慮只會讓我用它做核心業務系統,有一些比較獨立的小項目才會用;
這個框架我沒有具體去測試過它的性能,但從技術上猜測,應該返回List 會有一定消耗,因為用到反射,但實際項目中很少有大批量的List直接返回給用戶查看的;
關於ORM框架,目前有很多人開源的項目都很不錯,如果非要為這套框架提出點推薦理由, 勉為其難叫:簡單、輕便 吧;編譯完之后大概幾十K;從程序設計上不太復雜,所以在可讀性對於初級程序員來說比較容易,面對核心功能的擴展可能會比較棘手,但我認為還沒遇到可擴展的功能就提前做出來,代碼設計出空想的東西就屬於過度設計;
ORM框架名稱:ZhCun.DbCore
目前NuGet 版本分兩個,
1.2.0 與 2.2.0 ,其中 2.2.0 為 netstandard2.0 項目,可用於core 項目以及對應的 .Net Freamework 版本(好像是 .net 4.7 吧,具體可百度);1.2.0 在於.net 4.0 基礎上開發,代碼使用鏈接共享的;
代碼已經托管至“碼雲” ,https://gitee.com/zhcun/ORM
支持數據庫: SQL Server 、SQLite、Oracle、MySQL(因為兼容core的統一版本,OleDb目前暫不支持)
大概介紹一下基本功能及環境:
開發工具:VS 2019
開發框架:.Net 4.0 & netstandard2.0
支持Lamda,復雜對象查詢
新增與更新:支持自動識別賦值字段
支持數據過濾
支持各操作的方法擴展與重載
支持查看執行詳情(SQL、耗時 等)
支持實體類擴展自定義屬性
實體類
實體類中做過一些特殊處理,所以放Model的類庫也必須引用 ZhCun.DbCore ,並且繼承 EntityBase
實體類分 表(視圖)和存儲過程兩種類型,目前視圖和表並沒有區分開來,對於框架來說表和視圖是一樣的;
以下為表的實體類
using System; using ZhCun.DbCore.Entitys; namespace ZhCun.DbCore.Example.DbModels { public partial class TDevice : EntityBase { private System.Guid _Id; /// <summary> /// Id /// </summary> [EntityAttribute(ColumnName = CNId, IsPrimaryKey = true, IsNotNull = true)] public System.Guid Id { get { return _Id; } set { _Id = value; base.SetFieldChanged(CNId) ; } } private System.String _DevName; /// <summary> /// DevName /// </summary> [EntityAttribute(ColumnName = CNDevName)] public System.String DevName { get { return _DevName; } set { _DevName = value; base.SetFieldChanged(CNDevName) ; } } private System.Guid? _DevType; /// <summary> /// DevType /// </summary> [EntityAttribute(ColumnName = CNDevType)] public System.Guid? DevType { get { return _DevType; } set { _DevType = value; base.SetFieldChanged(CNDevType) ; } } private System.String _Remark; /// <summary> /// Remark /// </summary> [EntityAttribute(ColumnName = CNRemark)] public System.String Remark { get { return _Remark; } set { _Remark = value; base.SetFieldChanged(CNRemark) ; } } private System.DateTime? _CreateTime; /// <summary> /// CreateTime /// </summary> [EntityAttribute(ColumnName = CNCreateTime)] public System.DateTime? CreateTime { get { return _CreateTime; } set { _CreateTime = value; base.SetFieldChanged(CNCreateTime) ; } } private System.DateTime? _ModifyTime; /// <summary> /// ModifyTime /// </summary> [EntityAttribute(ColumnName = CNModifyTime)] public System.DateTime? ModifyTime { get { return _ModifyTime; } set { _ModifyTime = value; base.SetFieldChanged(CNModifyTime) ; } } private System.Guid? _UserId; /// <summary> /// UserId /// </summary> [EntityAttribute(ColumnName = CNUserId)] public System.Guid? UserId { get { return _UserId; } set { _UserId = value; base.SetFieldChanged(CNUserId) ; } } #region 字段名的定義 public const string CNId = "Id"; public const string CNDevName = "DevName"; public const string CNDevType = "DevType"; public const string CNRemark = "Remark"; public const string CNCreateTime = "CreateTime"; public const string CNModifyTime = "ModifyTime"; public const string CNUserId = "UserId"; #endregion } }
表實體類中當字段只發生過改變會通過 SetFieldChanged方法處理,它會自動判斷字段是否賦值,未賦值的字段不會進行增加與修改
實體類聲明了 partial 關鍵字,當需要擴展一些非表字段的屬性時建議使用不同的文件操作,這在實際應用中用處比較多;
實體類自動生成的代碼中包含字段名的常量,是為了在特殊情況使用sql查詢時盡量用該常量來表示字段名,這樣當字段設計發生變化更容易修改對應的代碼;
當使用擴展或自定義非表字段的屬性時需要標記為 IsNotField = true ,如下
[Entity(IsNotField =true)] public object Tag { set; get; }
其它屬性選項:
public class EntityAttribute : Attribute { /// <summary> /// 是否主鍵 /// </summary> public bool IsPrimaryKey { set; get; } /// <summary> /// 主鍵是否自動增長 /// </summary> public bool IsIdentity { set; get; } /// <summary> /// 是否非空字段 /// </summary> public bool IsNotNull { set; get; } /// <summary> /// 列名 /// </summary> public string ColumnName { set; get; } /// <summary> /// 默認false為字段屬性,如果為true則表示不是一個字段 /// </summary> public bool IsNotField { set; get; } } public class EntiryClassAttribute : Attribute { public string TableName { set; get; } }
存儲過程實體類示例:
public class P_AddUser : ProcEntityBase { public string LoginName { set; get; } public string LoginPwd { set; get; } public string UserName { set; get; } [ProcParam(ParamDirection = ParameterDirection.Output)] public string Message { set; get; } [ProcParam(ParamDirection = ParameterDirection.Output)] public bool Success { set; get; } }
存儲過程實體類特性定義:
/// <summary> /// 存儲過程參數的特性類 /// </summary> public class ProcParamAttribute : Attribute { public ProcParamAttribute() { _ParamDirection = ParameterDirection.Input; _OutSize =50; } public ProcParamAttribute(ParameterDirection paramDirection) { _ParamDirection = paramDirection; } ParameterDirection _ParamDirection; /// <summary> /// 存儲過程輸出參數的方向類型 /// </summary> public ParameterDirection ParamDirection { get { return _ParamDirection; } set { _ParamDirection = value; } } int _OutSize; /// <summary> /// 輸出參數的字節數,默認50個字節 /// </summary> public int OutSize { get { return _OutSize; } set { _OutSize = value; } } /// <summary> /// 是否oracle游標類型 /// </summary> public bool IsOracleCursor { set; get; } /// <summary> /// 參數名,空則使用屬性名代表參數名 /// </summary> public string ParameterName { set; get; } /// <summary> /// true表示非存儲過程參數 /// </summary> public bool NotParameter { set; get; } }
與表的實體類似,具體可查看備注說明;
實體類是ORM的核心部件,大部分操作都依賴實體類;
數據庫上下文(DBContext)
核心類 DBContext ,這與其它orm名稱可能有沖突,最早參考的EF起的名字,后來也沒變過;
雖然可以直接使用DBContext,但還是建議使用繼承他的子類,這也可以重寫你想改變或注入的業務邏輯;
早先版本的DBContext 是抽象出的接口,后來經過挺長時間的使用,發現並沒有其它實現,所以只用了一個核心的類來實現所有的數據庫操作了;
以下為DBContext實現功能列表,具體說明可查看源碼或着備注說明

1 // 2 // 摘要: 3 // 數據庫操作核心上下文 4 public class DBContext 5 { 6 public DBContext(EmDbType dbType, string connStr); 7 8 // 9 // 摘要: 10 // 數據庫操作對象 11 protected internal IDbHelper DbHelper { get; } 12 13 // 14 // 摘要: 15 // 創建查詢條件對象,分頁、排序; 16 public QueryCondition<TEntity> CreateQuery<TEntity>() where TEntity : EntityBase, new(); 17 // 18 // 摘要: 19 // 創建sql生成器 20 public virtual ISqlBuilder CreateSqlBuilder(); 21 // 22 // 摘要: 23 // 創建指定參數名稱前綴的sql生成器(解決參數名稱重復) 24 public virtual ISqlBuilder CreateSqlBuilder(string paramKey); 25 // 26 // 摘要: 27 // 創建執行的條件對象,不包含分頁、排序 28 public ExecCondition<TEntity> CreateWhere<TEntity>() where TEntity : EntityBase, new(); 29 // 30 // 摘要: 31 // 使用執行條件對象,進行刪除表達式 32 // 33 // 參數: 34 // execwhere: 35 // 執行條件對象 36 // 37 // 類型參數: 38 // TEntity: 39 // 實體對象類型 40 // 41 // 返回結果: 42 // 返回執行結果對象 43 public virtual ExecResult Delete<TEntity>(ICondition condition) where TEntity : EntityBase, new(); 44 // 45 // 摘要: 46 // 根據一個基本的表達式進行刪除操作 47 // 48 // 參數: 49 // lamda: 50 // 表達式 51 // 52 // 類型參數: 53 // TEntity: 54 // 實體對象類型 55 // 56 // 返回結果: 57 // 返回執行結果對象 58 public virtual ExecResult Delete<TEntity>(Expression<Func<TEntity, bool>> lamda) where TEntity : EntityBase, new(); 59 // 60 // 摘要: 61 // 根據主鍵刪除一條數據 62 public virtual ExecResult Delete<TEntity>(TEntity entity) where TEntity : EntityBase, new(); 63 // 64 // 摘要: 65 // 執行存儲過程的方法 66 // 67 // 參數: 68 // procObj: 69 // 存儲過程實體對象 70 // 71 // 類型參數: 72 // ProcEntity: 73 // ProcedureEntiryBase 74 // 75 // 返回結果: 76 // 返回存儲過程結果 77 public virtual ProcResult ExecProcedure<ProcEntity>(ProcEntity procObj) where ProcEntity : ProcEntityBase, new(); 78 // 79 // 摘要: 80 // 根據sql建造起執行sql語句 81 public virtual ExecResult ExecSql(ISqlBuilder sqlBuilder); 82 // 83 // 摘要: 84 // 新增一條記錄 85 public virtual ExecResult Insert<TEntity>(TEntity entity) where TEntity : EntityBase, new(); 86 // 87 // 摘要: 88 // 使用條件對象來進行復雜查詢 89 public virtual QueryResult<TEntity> Query<TEntity>(IQueryCondition condition, ISqlBuilder joinWhereBuilder) where TEntity : EntityBase, new(); 90 // 91 // 摘要: 92 // 根據查詢對象進行讀取數據庫,可返回DataTable、List 93 public virtual QueryResult<TEntity> Query<TEntity>(IQueryCondition condition) where TEntity : EntityBase, new(); 94 // 95 // 摘要: 96 // 使用表達式進行普通查詢 97 // 98 // 參數: 99 // lamda: 100 // 表達式 101 // 102 // 類型參數: 103 // TEntity: 104 // 實體對象類型 105 public virtual QueryResult<TEntity> Query<TEntity>(Expression<Func<TEntity, bool>> lamda) where TEntity : EntityBase, new(); 106 // 107 // 摘要: 108 // 根據一個sqlBuilder來構造where條件的查詢 109 // 110 // 參數: 111 // sqlBuilder: 112 // 可實現參數化查詢的sql文本構造器, 不包含 where 113 public virtual QueryResult<TEntity> Query<TEntity>(ISqlBuilder whereSqlBuilder) where TEntity : EntityBase, new(); 114 // 115 // 摘要: 116 // 根據一個sqlBuilder來構造一個完整的查詢 117 // 118 // 參數: 119 // sqlBuilder: 120 // 可實現參數化查詢的sql文本構造器 121 public virtual QueryResult Query(ISqlBuilder sqlBuilder); 122 public int QueryCount<TEntity>(Expression<Func<TEntity, bool>> lamda) where TEntity : EntityBase, new(); 123 public int QueryCount<TEntity>(IQueryCondition condition) where TEntity : EntityBase, new(); 124 public virtual ScalarResult QueryCountResult<TEntity>(IQueryCondition condition) where TEntity : EntityBase, new(); 125 public virtual ScalarResult QueryCountResult<TEntity>(Expression<Func<TEntity, bool>> lamda) where TEntity : EntityBase, new(); 126 public bool QueryExist<TEntity>(IQueryCondition condition) where TEntity : EntityBase, new(); 127 public bool QueryExist<TEntity>(Expression<Func<TEntity, bool>> lamda) where TEntity : EntityBase, new(); 128 public virtual ScalarResult QueryMax<TEntity>(Expression<Func<TEntity, object>> selector, IQueryCondition condition) where TEntity : EntityBase, new(); 129 // 130 // 摘要: 131 // 執行最大值函數查詢 132 public virtual ScalarResult QueryMax<TEntity>(Expression<Func<TEntity, object>> selector, Expression<Func<TEntity, bool>> lamda) where TEntity : EntityBase, new(); 133 public virtual ScalarResult QueryMin<TEntity>(Expression<Func<TEntity, object>> selector, Expression<Func<TEntity, bool>> lamda) where TEntity : EntityBase, new(); 134 public virtual ScalarResult QueryMin<TEntity>(Expression<Func<TEntity, object>> selector, IQueryCondition condition) where TEntity : EntityBase, new(); 135 // 136 // 摘要: 137 // 根據一個sqlBuilder 來構造一個完整的查詢,用於獲取首行首列值 138 // 139 // 參數: 140 // sqlBuilder: 141 // 可實現參數化查詢的sql文本構造器 142 public virtual ScalarResult QueryScalar(ISqlBuilder sqlBuilder); 143 public virtual ScalarResult QuerySum<TEntity>(Expression<Func<TEntity, object>> selector, Expression<Func<TEntity, bool>> lamda) where TEntity : EntityBase, new(); 144 public virtual ScalarResult QuerySum<TEntity>(Expression<Func<TEntity, object>> selector, IQueryCondition condition) where TEntity : EntityBase, new(); 145 // 146 // 摘要: 147 // 事務提交 148 public void TransCommit(); 149 // 150 // 摘要: 151 // 事務回滾 152 public void TransRollback(); 153 // 154 // 摘要: 155 // 事務開始 156 public void TransStart(); 157 // 158 // 摘要: 159 // where對象條件更新 160 public virtual ExecResult Update<TEntity>(TEntity entity, ICondition condition) where TEntity : EntityBase, new(); 161 // 162 // 摘要: 163 // 實體對象更新,主鍵必填 164 public virtual ExecResult Update<TEntity>(TEntity entity) where TEntity : EntityBase, new(); 165 // 166 // 摘要: 167 // lamda表達式更新 168 public virtual ExecResult Update<TEntity>(TEntity entity, Expression<Func<TEntity, bool>> lamda) where TEntity : EntityBase, new(); 169 // 170 // 摘要: 171 // 當使用sqlbuilder(所有實體類執行的Sql都會觸發)進行 更新、刪除、查詢、並指定具體實體類型時在執行前觸發, 用於數據過濾的統一處理; 需要子類重寫處理過程 172 protected virtual void BeforeExecSqlBuilder<TEntity>(ISqlBuilder sqlBuilder, EmDbOperation opType) where TEntity : EntityBase, new(); 173 // 174 // 摘要: 175 // 創建基於實體形參的where條件的sqlBuider對象(共通封裝) 176 protected virtual ISqlBuilder CreateQuerySqlBuilder<TEntity>() where TEntity : EntityBase, new(); 177 // 178 // 摘要: 179 // 使用表達式刪除的老大 180 protected virtual ExecResult DeleteBase<TEntity>(Func<ISqlBuilder, string> whereFun) where TEntity : EntityBase, new(); 181 // 182 // 摘要: 183 // 根據sql建造起執行sql語句,加上執行sql where文本 184 protected virtual ExecResult ExecSql(ISqlBuilder sqlBuilder, string sqlWhere); 185 // 186 // 摘要: 187 // 獲取實體對象值,不忽略主鍵值 188 protected Dictionary<string, object> GetEntityValue<TEntity>(TEntity entity) where TEntity : EntityBase, new(); 189 // 190 // 摘要: 191 // 獲取屬性值,指定是否忽略自增長主鍵 192 protected Dictionary<string, object> GetEntityValue<TEntity>(TEntity entity, bool ignorePK) where TEntity : EntityBase, new(); 193 // 194 // 摘要: 195 // 更新的老大 196 protected virtual ExecResult UpdateBase<TEntity>(TEntity entity, Func<ISqlBuilder, string> whereFun) where TEntity : EntityBase, new(); 197 }
新增 (DBContext.Insert)
TUser t = new TUser { Id = Guid.NewGuid(), UserName = "張三", LoginName = "zhangsan", LoginPwd = "12345" }; DBContext01 db = new DBContext01(); ExecResult r = db.Insert(t); Console.WriteLine("執行完成,影響 {0} 行", r.RowCount);
執行日志如下:
數據庫結果:
未賦值的字段不會生成sql語句;
更新 DBContext.Update

1 //根據主鍵自動條件更新 2 //只修改名字 3 var t = new TUser 4 { 5 Id = Guid.Parse("A0FCF84C-4EBD-4735-863A-205D8536DA93"), 6 UserName = "修改后的張三" 7 }; 8 DBContext01 db = new DBContext01(); 9 ExecResult r = db.Update(t);
這里的ModifyTime 同樣被修改了,是因為DBContext01 重寫更新的方法,將字段進行默認賦值;
刪除 DBContext.Delete (按主鍵)
1 //默認按主鍵條件刪除 2 var t = new TUser(); 3 t.Id = Guid.Parse("84DF3116-27A6-44E3-9E07-403F8B744932"); 4 DBContext01 db = new DBContext01(); 5 var r = db.Delete(t); 6 Console.WriteLine("執行完成,影響 {0} 行", r.RowCount);
當主鍵被賦值后默認使用主鍵進行刪除
刪除 DBContext.Delete (lamda 表達式條件)
//指定條件刪除 DBContext01 db = new DBContext01(); var r = db.Delete<TUser>(s => s.UserName == "張三"); Console.WriteLine("執行完成,影響 {0} 行", r.RowCount);
刪除 DBContext.Delete (where對象條件)
1 DBContext01 db = new DBContext01(); 2 var where = db.CreateWhere<TUser>(); 3 Guid id1 = Guid.Parse("A0FCF84C-4EBD-4735-863A-205D8536DA93"); 4 where.WhereAnd(s => s.WEx_In(s.Id, id1)); 5 var r = db.Delete<TUser>(where); 6 Console.WriteLine("執行完成,影響 {0} 行", r.RowCount);
事務
1 DBContext01 db = new DBContext01(); 2 try 3 { 4 db.TransStart(); 5 TUser user = new TUser(); 6 user.Id = Guid.NewGuid(); 7 user.UserName = "王五"; 8 user.LoginName = "wangwu"; 9 db.Insert(user); 10 11 TDevice dev = new TDevice(); 12 dev.Id = Guid.NewGuid(); 13 dev.DevName = "筆記本"; 14 db.Insert(dev); 15 16 db.TransCommit(); 17 Console.WriteLine("事務執行完成"); 18 } 19 catch (Exception ex) 20 { 21 db.TransRollback(); 22 Console.WriteLine(ex.Message); 23 }
查詢(DBContext.Query)- lamda 表達式 全部
1 //查詢所有數據 2 var db = new DBContext01(); 3 var r = db.Query<TUser>(s => true); 4 var rList = r.ToList();
查詢(DBContext.Query)- lamda 表達式
1 //使用lamad表達式查詢 2 var db = new DBContext01(); 3 var r = db.Query<TUser>(s => s.UserName == "張三"); 4 var rList = r.ToList(); 5 Common.PrintList(rList);
查詢(DBContext.Query)- query對象
1 //使用query對象查詢 2 var db = new DBContext01(); 3 var query = db.CreateQuery<TUser>(); 4 query.WhereAnd(s => s.WEx_Like(s.UserName, "%張三%")); 5 query.WhereOr(s => s.Email != null); 6 var r = db.Query<TUser>(query); 7 var rList = r.ToList();
查詢(DBContext.Query)- query對象 分頁查詢
1 var db = new DBContext01(); 2 //使用分頁查詢 3 var query = db.CreateQuery<TUser>(); 4 query.PageNo = 2; 5 query.PageSize = 3; 6 query.WhereAnd(s => s.UserName != null).OrderBy(s => s.UserName); 7 var r = db.Query<TUser>(query); 8 var rList = r.ToList();
查詢(DBContext.Query) - SQL語句條件查詢List
1 var db = new DBContext01(); 2 //使用sql語句的where查詢 3 var sqlBuilder = db.CreateSqlBuilder(); 4 //使用參數化查詢 5 sqlBuilder.AddSQLText("LoginName in ({0},{1})", 6 sqlBuilder.AddParam("zhangsan"), 7 sqlBuilder.AddParam("lisi")); 8 var r = db.Query<TUser>(sqlBuilder); 9 var rList = r.ToList();
查詢(DBContext.Query) - SQL語句查詢DataTable
1 var db = new DBContext01(); 2 //使用sql語句查詢得到DataTable 3 db.CreateSqlBuilder(); 4 var sqlBuilder = db.CreateSqlBuilder(); 5 //使用參數化查詢 6 sqlBuilder.AddSQLText("select * from TUser where LoginName in ('zhangsan','lisi')"); 7 var r = db.Query(sqlBuilder); 8 var data = r.ToDataTable();
注意:當使用Sql語句查詢只能得到 DataTable
存儲過程(DBContext.ExecProcedure)- 執行
1 P_AddUser p = new P_AddUser(); 2 p.LoginName = "張存"; 3 p.LoginPwd = "112233"; 4 p.UserName = ""; 5 var db = new DBContext01(); 6 var r = db.ExecProcedure(p); 7 r.ExecProc();
存儲過程(DBContext.ExecProcedure)- 查詢
1 P_GetUser p = new P_GetUser(); 2 var db = new DBContext01(); 3 var r = db.ExecProcedure(p); 4 var rList = r.ToList<TUser>();
數據過濾及默認賦值 DBContext 重寫
1 class DBContext01 : DBContextBase 2 { 3 Guid _loginUserId; 4 5 public void SetLoginUserId(Guid loginUserId) 6 { 7 _loginUserId = loginUserId; 8 } 9 10 /// <summary> 11 /// 根據屬性名設置對象的屬性值 12 /// </summary> 13 public static void SetPropertyValue<T>(T obj, string pName, object pValue) where T : class, new() 14 { 15 Type t = typeof(T); 16 PropertyInfo pInfo = t.GetProperty(pName, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance); 17 18 if (pInfo != null && pInfo.CanWrite) 19 { 20 if (pValue == null || DBNull.Value.Equals(pValue) || Guid.Empty.Equals(pValue)) 21 { 22 return; 23 } 24 string pTypeName = pInfo.PropertyType.Name.ToUpper(); 25 if (pTypeName == "GUID") 26 { 27 pValue = new Guid(pValue.ToString()); 28 } 29 else 30 { 31 pValue = Convert.ChangeType(pValue, pInfo.PropertyType); 32 } 33 pInfo.SetValue(obj, pValue, null); 34 } 35 } 36 /// <summary> 37 /// 結果完成的處理方法,如:寫入日志 38 /// </summary> 39 protected override void ResultFinish(BaseResult result) 40 { 41 //Task.Factory.StartNew(() => { }); 42 var sql = result.SqlContent; 43 Console.WriteLine("執行標記:{0}", result.ResultMark); 44 Console.WriteLine("SQL:{0}", sql); 45 Console.WriteLine("耗時:{0}", result.ExecInterval); 46 Console.WriteLine("所影響行:{0}", result.RowCount); 47 Console.WriteLine(); 48 } 49 public override ExecResult Insert<TEntity>(TEntity entity) 50 { 51 //如果該實體有“UserId”字段那么缺省賦值為:_loginUserId 值 52 SetPropertyValue(entity, "UserId", _loginUserId); 53 //如果字段Id沒有被賦值,則賦值默認字段為新的Guid 54 if (!entity.IsChangeField("Id")) 55 { 56 SetPropertyValue(entity, "Id", Guid.NewGuid()); 57 } 58 //如果實體有“CreateTime” 字段,設置為當前時間 59 SetPropertyValue(entity, "CreateTime", DateTime.Now); 60 return base.Insert<TEntity>(entity); 61 } 62 protected override ExecResult UpdateBase<TEntity>(TEntity entity, Func<ISqlBuilder, string> whereFun) 63 { 64 SetPropertyValue(entity, "ModifyTime", DateTime.Now); 65 return base.UpdateBase<TEntity>(entity, whereFun); 66 } 67 protected override void BeforeExecSqlBuilder<TEntity>(ISqlBuilder sqlBuilder, EmDbOperation opType) 68 { 69 //user 沒有UserId 字段加上過濾 70 if (typeof(TEntity) == typeof(TUser)) 71 { 72 return; 73 } 74 //判斷當前執行方法是否指定了過濾條件 75 if (QueryFilterHelper.IsFilter()) 76 { 77 //追加sql文本,同時會把所有已有條件加上括號,並加上and符號 78 sqlBuilder.AddSqlTextByGroup(" UserId = {0}", sqlBuilder.AddParam(_loginUserId)); 79 } 80 } 81 }
數據過濾用於實現當不同用戶、角色、部門 等 查詢條件的全局處理;
今天先寫這么多吧,最后的幾個小節說明有點少;
共享出來也是為了進步,也希望會有人指出不足以改正缺陷;
前幾天翻過幾篇.Net 比較好的ORM框架,有很多輕量級的都已經很成熟了,功能也很全面;
個人認為現在公司選擇ORM框架分兩種:1. 用自己的ORM,便於處理業務上的個性需求。2.用官網常用的ORM框架(如:EF),大眾貨,功能全,很多“學生”時代都已經納入“課本”的學習標准;
不管怎么樣,也希望這個開源項目能對新手或者打算寫自己ORM框架的人有所幫助