使用表示式樹+反射實現簡易ORM物件對映操作
阿新 • • 發佈:2018-12-30
使用表示式樹+反射實現簡易ORM物件對映操作
為了簡單起見我就建立一個檔案 BaseDAL.cs , 使用方法也非常簡單,看程式碼吧
先建立一個Model
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BaseDAL.Model
{
[Table("UserInfo")]
public class MdUserInfo
{
/// <summary>
/// 使用者編號
/// </summary>
///
[PrimaryKey]
public string UserNo { set; get; }
/// <summary>
/// 門店編號
/// </summary>
public string ShopNo { set; get; }
/// <summary>
/// 使用者姓名
/// </summary>
public string UserNamc { set ; get; }
}
}
然後在建立一個UserInfoDAL類繼承自BaseDAL
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BaseDAL.Model;
namespace BaseDAL.DAL
{
public class UserInfoDAL:BaseDAL<MdUserInfo>
{
}
}
好 接下來就是使用示例了
using BaseDAL.DAL;
using BaseDAL.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BaseDAL
{
class Program
{
static void Main(string[] args)
{
UserInfoDAL userInfoDAL = new UserInfoDAL();
//查
List<MdUserInfo> listUser = userInfoDAL.Query(p => p.UserNamc.Contains("馬") && p.UserNo == "00008");
//改
for (int i = 0; i < listUser.Count; i++)
{
listUser[i].UserNamc = listUser[i].UserNamc + i;
userInfoDAL.Update(listUser[i]);
}
//增
MdUserInfo userInfo = new MdUserInfo();
userInfo.UserNo = "00001";
userInfo.UserNamc = "測試新增";
userInfo.ShopNo = "10";
userInfoDAL.Insert(userInfo);
//刪
userInfoDAL.Delete(p => p.UserNo == "00001");
}
}
}
主要實現思路就是利用Expression表示式樹+反射,還有就是使用了Attribute來對類進行標註,簡簡單單400行程式碼 ٩(๑❛ᴗ❛๑)۶
BaseDAL.cs程式碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Data.SqlClient;
using System.Data;
using System.Reflection;
namespace BaseDAL
{
/// <summary>
/// 資料基礎訪問類
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public class BaseDAL<TEntity> where TEntity : class
{
/// <summary>
/// 資料庫連線字串
/// </summary>
public static string SqlConnection = "server=192.168.1.12;database=EatPos2;uid=sa;pwd=1234;";
/// <summary>
/// 當前操作表名稱
/// </summary>
public string TableName { get; private set; }
/// <summary>
/// 表列
/// </summary>
private DataColumnCollection TableColumns { set;get; }
/// <summary>
/// Model屬性列表
/// </summary>
private List<PropertyInfo> listProperty = new List<PropertyInfo>();
/// <summary>
/// 當前表主鍵
/// </summary>
private List<PropertyInfo> listPrimaryKey = new List<PropertyInfo>();
/// <summary>
/// 標註自增列屬性
/// </summary>
private PropertyInfo AutoIncrease = null;
public BaseDAL()
{
Type type = typeof(TEntity);
#region 初始化表名稱
object[] objs = type.GetCustomAttributes(typeof(TableAttribute), false);
if (objs.Length > 0)
{
TableAttribute table = objs[0] as TableAttribute;
TableName = table.TableName;
}
else
{
TableName = type.Name;
}
#endregion
#region 初始化屬性列表
PropertyInfo[] propertys = type.GetProperties();
listProperty = new List<PropertyInfo>(propertys);
foreach (PropertyInfo property in listProperty)
{
Attribute primary = property.GetCustomAttribute(typeof(PrimaryKeyAttribute));
if(primary!=null )
{
listPrimaryKey.Add(property);
}
Attribute autoIncrease = property.GetCustomAttribute(typeof(AutoIncreaseAttribute));
if (autoIncrease != null)
{
AutoIncrease = property;
}
}
#endregion
}
/// <summary>
/// 查詢
/// </summary>
/// <param name="expression"></param>
/// <returns></returns>
public List<TEntity> Query(Expression<Func<TEntity, bool>> expression = null)
{
StringBuilder buff = new StringBuilder();
if (expression != null)
{
ExpressionHelper.ParseExpression(expression.Body, buff);
}
string strSql = string.Format("Select * From {0} ",TableName);
if (buff.Length > 0)
{
strSql += " Where "+buff.ToString();
}
List<TEntity> listEntity = new List<TEntity>();
DataTable table = SqlHelper.ExecuteTable(strSql);
TableColumns = table.Columns;
foreach (DataRow dataRow in table.Rows)
{
TEntity model = DataRowToEntity(dataRow);
listEntity.Add(model);
}
return listEntity;
}
/// <summary>
/// 更新
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int Update(TEntity model)
{
#region 構建set欄位
StringBuilder setbuff = new StringBuilder();
foreach (PropertyInfo property in listProperty)
{
if (listPrimaryKey.Contains(property))
continue;
if (setbuff.Length > 0)
{
setbuff.Append(",");
}
object value = property.GetValue(model);
setbuff.AppendFormat("{0}={1}", property.Name, ExpressionHelper.GetSqlValue(value));
}
#endregion
#region 構建where欄位
string strWhere="";
if (listPrimaryKey.Count > 0)
{
foreach (PropertyInfo property in listPrimaryKey)
{
if (strWhere != "")
{
strWhere += " And ";
}
object value = property.GetValue(model);
strWhere += string.Format("{0}={1}", property.Name, ExpressionHelper.GetSqlValue(value));
}
strWhere = " Where " + strWhere;
}
#endregion
string strSql = string.Format("Update {0} Set {1} {2}",TableName,setbuff.ToString(),strWhere);
return SqlHelper.ExecuteSql(strSql);
}
/// <summary>
/// 增加
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int Insert(TEntity model)
{
StringBuilder fieldName = new StringBuilder();
StringBuilder fieldValue = new StringBuilder();
foreach (PropertyInfo property in listProperty)
{
if (AutoIncrease != null && property.Equals(AutoIncrease))
continue;
if (fieldName.Length > 0)
{
fieldName.Append(",");
fieldValue.Append(",");
}
fieldName.Append(property.Name);
fieldValue.Append(ExpressionHelper.GetSqlValue(property.GetValue(model)));
}
string strSql = string.Format("Insert Into {0}({1}) Values({2})",TableName,fieldName.ToString(),fieldValue.ToString());
if (AutoIncrease != null)
{
strSql += "\r\n;select @@IDENTITY";
object obj = SqlHelper.ExecuteScalar(strSql);
AutoIncrease.SetValue(model, obj);
return Convert.ToInt32(obj);
}
return SqlHelper.ExecuteSql(strSql);
}
/// <summary>
/// 刪除
/// </summary>
/// <param name="expression"></param>
/// <returns></returns>
public int Delete(Expression<Func<TEntity, bool>> expression)
{
StringBuilder buff = new StringBuilder();
if (expression != null)
{
ExpressionHelper.ParseExpression(expression.Body, buff);
}
string strSql = string.Format("Delete From {0} ", TableName);
if (buff.Length > 0)
{
strSql += " Where " + buff.ToString();
}
return SqlHelper.ExecuteSql(strSql);
}
#region 私有方法
/// <summary>
/// 轉換成Model
/// </summary>
/// <param name="dataRow"></param>
/// <returns></returns>
private TEntity DataRowToEntity(DataRow dataRow)
{
ConstructorInfo construct = typeof(TEntity).GetConstructor(new Type[]{});
object model = construct.Invoke(null);
for (int i = 0; i < listProperty.Count; i++)
{
PropertyInfo property = listProperty[i];
if (TableColumns.Contains(property.Name))
{
property.SetValue(model, dataRow[property.Name], null);
}
}
return model as TEntity;
}
#endregion
}
#region ExpressionHelper + 表示式幫助類
/// <summary>
/// 表示式幫助類
/// </summary>
class ExpressionHelper
{
/// <summary>
/// 解析Where條件
/// </summary>
/// <param name="expression"></param>
/// <param name="buff"></param>
public static void ParseExpression(Expression expression, StringBuilder buff)
{
BinaryExpression binary = null;
MemberExpression left = null;
ConstantExpression rigth = null;
if (expression.NodeType == ExpressionType.AndAlso)
{
ParseExpression((expression as System.Linq.Expressions.BinaryExpression).Left, buff);
buff.Append(" And ");
ParseExpression((expression as System.Linq.Expressions.BinaryExpression).Right, buff);
}
else if (expression.NodeType == ExpressionType.OrElse)
{
ParseExpression((expression as System.Linq.Expressions.BinaryExpression).Left, buff);
buff.Append(" Or ");
ParseExpression((expression as System.Linq.Expressions.BinaryExpression).Right, buff);
}
else if (expression.NodeType == ExpressionType.Call)
{
MethodCallExpression call = expression as MethodCallExpression;
string methodName = call.Method.Name;
if (methodName == "Contains")
{
left = call.Object as MemberExpression;
rigth = call.Arguments[0] as ConstantExpression;
buff.AppendFormat("{0} like '%{1}%'", left.Member.Name, rigth.Value);
}
}
else
{
binary = expression as System.Linq.Expressions.BinaryExpression;
left = binary.Left as MemberExpression;
rigth = binary.Right as ConstantExpression;
switch (expression.NodeType)
{
case ExpressionType.Equal:
buff.AppendFormat("{0} = {1}", left.Member.Name, GetSqlValue(rigth.Value));
break;
case ExpressionType.NotEqual:
buff.AppendFormat("{0} <> {1}", left.Member.Name, GetSqlValue(rigth.Value));
break;
case ExpressionType.GreaterThan:// 大於
buff.AppendFormat("{0} > {1}", left.Member.Name, GetSqlValue(rigth.Value));
break;
case ExpressionType.GreaterThanOrEqual:// 大於等於
buff.AppendFormat("{0} >= {1}", left.Member.Name, GetSqlValue(rigth.Value));
break;
case ExpressionType.LessThan:// 小於
buff.AppendFormat("{0} < {1}", left.Member.Name, GetSqlValue(rigth.Value));
break;
case ExpressionType.LessThanOrEqual:// 小於等於
buff.AppendFormat("{0} <= {1}", left.Member.Name, GetSqlValue(rigth.Value));
break;
}
}
return;
}
/// <summary>
/// 取Sql引數值
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static string GetSqlValue(object obj)
{
if (obj == null)
return "";
if (obj.GetType().Equals(typeof(string)))
{
return string.Format("'{0}'", obj.ToString());
}
else if (obj.GetType().Equals(typeof(DateTime)))
{
return string.Format("'{0}'", Convert.ToDateTime(obj).ToString("yyyy-MM-dd HH:mm:ss"));
}
else if (obj.GetType().Equals(typeof(int)) || obj.GetType().Equals(typeof(double)) || obj.GetType().Equals(typeof(float)))
{
return obj.ToString();
}
else if (obj.GetType().Equals(typeof(bool)))
{
bool value = Convert.ToBoolean(obj);
return value ? "1" : "0";
}
return "";
}
}
#endregion
#region 特性標註
#region TableAttribute +對映表名稱標註
/// <summary>
/// 對映表名稱標註
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class TableAttribute : Attribute
{
/// <summary>
/// 表名稱
/// </summary>
public string TableName { set; get; }
public TableAttribute(string _tableName)
{
this.TableName = _tableName;
}
}
#endregion
#region PrimaryKeyAttribute +對映主鍵標註
[AttributeUsage(AttributeTargets.Property)]
public class PrimaryKeyAttribute : Attribute
{
}
#endregion
#region AutoIncreaseAttribute +對映自增列標註
[AttributeUsage(AttributeTargets.Property)]
public class AutoIncreaseAttribute : Attribute
{
}
#endregion
#endregion
#region SqlHelper
class SqlHelper {
public static DataTable ExecuteTable(string strSql)
{
using (SqlConnection conn = new SqlConnection(BaseDAL<object>.SqlConnection))
{
SqlDataAdapter adapter = new SqlDataAdapter(strSql, conn);
DataTable table=new DataTable();
adapter.FillSchema(table,SchemaType.Mapped);
adapter.Fill(table);
return table;
}
}
public static int ExecuteSql(string strSql)
{
using (SqlConnection conn = new SqlConnection(BaseDAL<object>.SqlConnection))
{
conn.Open();
SqlCommand cmd = new SqlCommand(strSql, conn);
return cmd.ExecuteNonQuery();
}
}
public static object ExecuteScalar(string strSql)
{
using (SqlConnection conn = new SqlConnection(BaseDAL<object>.SqlConnection))
{
conn.Open();
SqlCommand cmd = new SqlCommand(strSql, conn);
return cmd.ExecuteScalar();
}
}
}
#endregion
}
下載連結:http://pan.baidu.com/s/1midzwes 密碼:mbvx