自定义简单的ORM框架
项目中的ORM(Object Relational Mapping)映射,多是一个项目构成的基础。 项目中直接操作odbc十分麻烦。
ADO.net返回的Table要映射到具体的类上面,还需要手动的编码。十分耗时。通过反射实现一个简单的ORM框架。
1. 定义ColumnAttribute,主要加在属性列上,用于标示和数据表中的列名
[AttributeUsage(AttributeTargets.Field|AttributeTargets.Property,AllowMultiple=false,Inherited=false)]
public class ColumnAttribute:Attribute
{
public ColumnAttribute(string columnName)
{
this.Value = columnName;
}
public string Value { get; protected set; }
}
2. 定义TableAtrribute,主要加在Model类上,用于标示和关联数据库表名。
[AttributeUsage(AttributeTargets.Class)]
public class TableAtrribute:Attribute
{
public string Value { get; protected set; }
public TableAtrribute(string tablename)
{
this.Value = tablename;
}
}
3.定义AttributeProcess类,获取指定类,映射的表名和列名
///
/// DB Table Name
///
///
///
public static string GetTableName(Type type)
{
string tableName = string.Empty;
object[] attributes = type.GetCustomAttributes(false);
foreach (var attr in attributes)
{
if(attr is TableAtrribute)
{
TableAtrribute tableAtrribute = attr as TableAtrribute;
tableName = tableAtrribute.Value;
}
}
if (string.IsNullOrEmpty(tableName))
{
tableName = type.Name;
}
//Todo
return tableName;
}
///
/// DB Table Column Name
///
///
///
public static string GetColumnName(PropertyInfo property)
{
string columnName = string.Empty;
object[] attributes = property.GetCustomAttributes(false);
foreach (var attr in attributes)
{
if (attr is ColumnAttribute)
{
ColumnAttribute columnAttr = attr as ColumnAttribute;
columnName = columnAttr.Value;
}
}
if(string.IsNullOrEmpty(columnName))
{
columnName = property.Name;
}
return columnName;
}
4.具体Model类上,使用TableAttribute和ColumnAttribute进行标记
如
[TableAtrribute("Customer")]
public class Customer
{
[Column("CustomerID")]
public int CustomerID { get; set; }
[Column("Email")]
public string Email { get; set; }
[Column("CustomerName")]
public string CustomerName { get; set; }
}
5.定义ADO.net操作类DBBase
///
/// open DB Connection
///
public void OpenDB()
{
try
{
switch (DbConfig.Type)
{
case DbType.SqlServer:
{
dbConnection = new SqlConnection(DbConfig.DbString);
break;
}
}
dbConnection.Open();
}
catch (Exception ex)
{
throw ex;
}
finally
{
}
}
///
/// close DB Connection
///
public void CloseSqlConnection()
{
if (dbCommand != null)
{
dbCommand.Dispose();
}
dbCommand = null;
if (reader != null)
{
reader.Dispose();
}
reader = null;
if (dbConnection != null && dbConnection.State == System.Data.ConnectionState.Open)
{
dbConnection.Close();
dbConnection.Dispose();
}
dbConnection = null;
}
///
/// Execute
///
///
///
///
public DbDataReader ExecuteReader(string sql, Dictionary
{
OpenDB();
dbCommand = dbConnection.CreateCommand();
dbCommand.CommandText = sql;
if (parameters != null && parameters.Count() > 0)
{
foreach (var param in parameters)
{
dbCommand.Parameters.Add(new SqlParameter(param.Key, param.Value));
};
}
reader = dbCommand.ExecuteReader();
return reader;
}
6.实现ORM映射类
///
/// get result basic on sql result and reflect to Model
///
///
///
///
public List
{
try
{
List
var reader = this.dbBase.ExecuteReader(sql.GetSql(), sql.GetParams());
Type type = typeof(T);
if (type.IsPrimitive || type == typeof(string) || type == typeof(DateTime) || type.IsEnum)
{
while (reader.Read())
{
if (type.IsEnum)
{
list.Add((T)Enum.ToObject(type, reader.GetValue(0)));
}
else
{
list.Add((T)Convert.ChangeType(reader.GetValue(0), type));
}
}
}
else
{
while (reader.Read())
{
// 创建对象实例
T result = Activator.CreateInstance
// 取得类上定义的所有属性
PropertyInfo[] properties = type.GetProperties();
foreach (PropertyInfo property in properties)
{
// 取得某个属性上附带的ColumnAttribute保存的ColumnName
string columnName = AttributeProcess.GetColumnName(property);
if (property.PropertyType.IsEnum)
{
property.SetValue(result, Enum.ToObject(property.PropertyType, reader.GetValue(reader.GetOrdinal(columnName))), null);
}
else
{
//1. 根据columnName取出reader 里面的值reader.GetValue(reader.GetOrdinal(columnName))
//把第一步取得的值放到result对象中对应的property属性上
property.SetValue(result, Convert.ChangeType(reader.GetValue(reader.GetOrdinal(columnName)), property.PropertyType));
}
}
list.Add(result);
}
}
return list;
}
catch (Exception ex)
{
throw ex;
}
finally
{
dbBase.CloseSqlConnection();
}
}