using System; using System.Collections.Generic; using System.Text; using CYQ.Data.Table; using System.Reflection; using CYQ.Data.Tool; using CYQ.Data.Cache; using CYQ.Data.SQL; using System.Data; using CYQ.Data.Aop; namespace CYQ.Data.Orm { /// /// ORM CodeFirst 字段来源 /// public enum FieldSource { /// /// 从实体属性来 /// Property, /// /// 从数据库或文本数据来 /// Data, /// /// 综合以上两者 /// BothOfAll } /// /// 简单ORM基类(纯数据交互功能) /// public class SimpleOrmBase : IDisposable { internal MDataColumn Columns = null; /// /// 标识是否允许写日志。 /// internal bool AllowWriteLog { set { Action.dalHelper.isAllowInterWriteLog = value; } } /// /// 是否启用了AOP拦截设置字段值同步。 /// internal bool IsUseAop = false; private static FieldSource _FieldSource = FieldSource.BothOfAll; /// /// 字段来源(当字段变更时,可以设置此属性来切换更新) /// public static FieldSource FieldSource { get { return _FieldSource; } set { _FieldSource = value; } } Object entity;//实体对象 Type typeInfo;//实体对象类型 private MAction _Action; internal MAction Action { get { if (_Action == null) { SetDelayInit(_entityInstance, _tableName, _conn, _op);//延迟加载 } return _Action; } } /// /// 构造函数 /// public SimpleOrmBase() { } /// /// 设置Aop状态 /// /// public void SetAopState(AopOp op) { Action.SetAopState(op); } /// /// 初始化状态[继承此基类的实体在构造函数中需调用此方法] /// /// 实体对象,一般写:this protected void SetInit(Object entityInstance) { SetInit(entityInstance, null, AppConfig.DB.DefaultConn); } /// /// 初始化状态[继承此基类的实体在构造函数中需调用此方法] /// /// 实体对象,一般写:this /// 表名,如:Users protected void SetInit(Object entityInstance, string tableName) { SetInit(entityInstance, tableName, AppConfig.DB.DefaultConn); } /// /// 初始化状态[继承此基类的实体在构造函数中需调用此方法] /// /// 实体对象,一般写:this /// 表名,如:Users /// 数据链接,单数据库时可写Null,或写默认链接配置项:"Conn",或直接数据库链接字符串 protected void SetInit(Object entityInstance, string tableName, string conn) { SetInit(entityInstance, tableName, conn, AopOp.OpenAll); } private object _entityInstance; private string _tableName; private string _conn; private AopOp _op; protected void SetInit(Object entityInstance, string tableName, string conn, AopOp op) { _entityInstance = entityInstance; _tableName = tableName; _conn = conn; _op = op; } /// /// 将原有的初始化改造成延时加载。 /// private void SetDelayInit(Object entityInstance, string tableName, string conn, AopOp op) { conn = string.IsNullOrEmpty(conn) ? AppConfig.DB.DefaultConn : conn; entity = entityInstance; typeInfo = entity.GetType(); try { if (string.IsNullOrEmpty(tableName)) { tableName = typeInfo.Name; if (tableName.EndsWith(AppConfig.EntitySuffix)) { tableName = tableName.Substring(0, tableName.Length - AppConfig.EntitySuffix.Length); } } string key = tableName + StaticTool.GetHashKey(conn); if (!CacheManage.LocalInstance.Contains(key)) { DalType dal = DBTool.GetDalType(conn); bool isTxtDal = dal == DalType.Txt || dal == DalType.Xml; string errMsg = string.Empty; Columns = DBTool.GetColumns(tableName, conn, out errMsg);//内部链接错误时抛异常。 if (Columns == null || Columns.Count == 0) { if (errMsg != string.Empty) { Error.Throw(errMsg); } Columns = TableSchema.GetColumns(typeInfo); if (!DBTool.ExistsTable(tableName, conn)) { DBTool.ErrorMsg = null; if (!DBTool.CreateTable(tableName, Columns, conn)) { Error.Throw("SimpleOrmBase :Create Table Error:" + tableName + DBTool.ErrorMsg); } } } else if (isTxtDal)//文本数据库 { if (FieldSource != FieldSource.Data) { MDataColumn c2 = TableSchema.GetColumns(typeInfo); if (FieldSource == FieldSource.BothOfAll) { Columns.AddRange(c2); } else { Columns = c2; } } } if (Columns != null && Columns.Count > 0) { CacheManage.LocalInstance.Set(key, Columns, 1440, null); } } else { Columns = CacheManage.LocalInstance.Get(key) as MDataColumn; } _Action = new MAction(Columns.ToRow(tableName), conn); if (typeInfo.Name == "SysLogs") { _Action.SetAopState(Aop.AopOp.CloseAll); } else { _Action.SetAopState(op); } _Action.EndTransation(); } catch (Exception err) { if (typeInfo.Name != "SysLogs") { Log.WriteLogToTxt(err); } throw; } } internal void SetInit2(Object entityInstance, string tableName, string conn, AopOp op) { SetInit(entityInstance, tableName, conn, op); } internal void SetInit2(Object entityInstance, string tableName, string conn) { SetInit(entityInstance, tableName, conn); } internal void Set(object key, object value) { if (Action != null) { Action.Set(key, value); } } #region 基础增删改查 成员 #region 插入 /// /// 插入数据 /// public bool Insert() { return Insert(InsertOp.ID); } /// /// 插入数据 /// /// 插入选项 public bool Insert(InsertOp option) { return Insert(false, option, false); } /// /// 插入数据 /// /// 插入主键 public bool Insert(InsertOp option, bool insertID) { return Insert(false, option, insertID); } /* /// /// 插入数据 /// /// 自动从控制获取值 internal bool Insert(bool autoSetValue) { return Insert(autoSetValue, InsertOp.ID); } internal bool Insert(bool autoSetValue, InsertOp option) { return Insert(autoSetValue, InsertOp.ID, false); }*/ /// /// 插入数据 /// /// 自动从控制获取值 /// 插入选项 /// 插入主键 internal bool Insert(bool autoSetValue, InsertOp option, bool insertID) { if (autoSetValue) { Action.UI.GetAll(!insertID); } GetValueFromEntity(); Action.AllowInsertID = insertID; bool result = Action.Insert(false, option); if (autoSetValue || option != InsertOp.None) { SetValueToEntity(); } return result; } #endregion #region 更新 /// /// 更新数据 /// public bool Update() { return Update(null, false); } /// /// 更新数据 /// /// where条件,可直接传id的值如:[88],或传完整where条件如:[id=88 and name='路过秋天'] public bool Update(object where) { return Update(where, false); } /// /// 更新数据 /// /// where条件,可直接传id的值如:[88],或传完整where条件如:[id=88 and name='路过秋天'] /// 是否自动获取值[自动从控件获取值,需要先调用SetAutoPrefix或SetAutoParentControl方法设置控件前缀] internal bool Update(object where, bool autoSetValue) { if (autoSetValue) { Action.UI.GetAll(false); } GetValueFromEntity(); bool result = Action.Update(where); if (autoSetValue) { SetValueToEntity(); } return result; } #endregion #region 删除 /// /// 删除数据 /// public bool Delete() { return Delete(null); } /// /// 删除数据 /// /// where条件,可直接传id的值如:[88],或传完整where条件如:[id=88 and name='路过秋天'] public bool Delete(object where) { GetValueFromEntity(); return Action.Delete(where); } #endregion #region 查询 /// /// 查询1条数据 /// public bool Fill() { return Fill(null); } /// /// 查询1条数据 /// public bool Fill(object where) { bool result = Action.Fill(where); if (result) { SetValueToEntity(); } return result; } /// /// 列表查询 /// public List Select() { int count = 0; return Select(0, 0, null, out count); } /// /// 列表查询 /// /// 查询条件[可附带 order by 语句] /// public List Select(string where) { int count = 0; return Select(0, 0, where, out count); } /// /// 列表查询 /// /// 查询几条 /// 查询条件[可附带 order by 语句] /// public List Select(int topN, string where) { int count = 0; return Select(0, topN, where, out count); } public List Select(int pageIndex, int pageSize) { int count = 0; return Select(pageIndex, pageSize, null, out count); } public List Select(int pageIndex, int pageSize, string where) { int count = 0; return Select(pageIndex, pageSize, where, out count); } /// /// 带分布功能的选择[多条件查询,选择所有时只需把PageIndex/PageSize设置为0] /// /// 第几页 /// 每页数量[为0时默认选择所有] /// 查询条件[可附带 order by 语句] /// 返回的记录总数 public List Select(int pageIndex, int pageSize, string where, out int count) { return Action.Select(pageIndex, pageSize, where, out count).ToList(); } internal MDataTable Select(int pageIndex, int pageSize, string where, out int count) { return Action.Select(pageIndex, pageSize, where, out count); } /// /// 获取记录总数 /// public int GetCount(object where) { return Action.GetCount(where); } /// /// 查询是否存在指定的条件的数据 /// public bool Exists(object where) { return Action.Exists(where); } #endregion #endregion internal void SetValueToEntity() { SetValueToEntity(null); } internal void SetValueToEntity(string propName) { if (!string.IsNullOrEmpty(propName)) { PropertyInfo pi = typeInfo.GetProperty(propName); if (pi != null) { MDataCell cell = Action.Data[propName]; if (cell != null && !cell.IsNull) { try { pi.SetValue(entity, cell.Value, null); } catch { } } } } else { Action.Data.SetToEntity(entity); } } private void GetValueFromEntity() { if (!IsUseAop || AppConfig.IsAspNetCore)//ASPNETCore下,动态代理的Aop是无效的 { Action.Data.LoadFrom(entity, BreakOp.Null); } } #region IDisposable 成员 /// /// 释放资源 /// public void Dispose() { if (Action != null) { Action.Dispose(); } } #endregion } }