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
}
}