利用反射+特性实现简单的实体映射数据库操作类(还未做自动生成SQL语句部分)
写了一个数据库操作类,达到通过实体自动映射数据库进行查询,添加,删除,修改操作,啥也不说了,直接上代码:
反回一个实体,通过枚举参数确定使用属性/特性进行字段映射(转款做表和主键映射)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/// <summary>
/// 获取单个实体
/// </summary>
/// <typeparam name="TEntity">实体(泛型)</typeparam>
/// <param name="cmdText">命令</param>
/// <param name="commandType">命令类型</param>
/// <param name="exeEntityType">按属性/特性映射</param>
/// <param name="paramers">参数数组</param>
/// <returns>实体</returns>
public static TEntity GetEntity<TEntity>(string cmdText, CommandType commandType,AppEnum.ExeEntityType exeEntityType,params DbParameter[] paramers) where TEntity:new()
{
TEntity entity = new TEntity();
using (IDataReader reader = DbHelper.CreateDataReader(cmdText, commandType, paramers))
{
if (reader.Read())
{
Type entityType = entity.GetType();
PropertyInfo[] propertyInfos=entityType.GetProperties();
foreach(PropertyInfo property in propertyInfos)
{
if (exeEntityType == AppEnum.ExeEntityType.isAttribute)
{
DataFieldAttribute datafieldAttribute = GetDataFieldAttribute(property);
if (datafieldAttribute == null)
throw new AssionException("AppEnum.ExeEntityType枚举为 isAttribute 时,实体类需要指定特性!");
if (!(reader[datafieldAttribute.FieldName] is DBNull))
property.SetValue(entity, reader[datafieldAttribute.FieldName], null);
}
else if (exeEntityType == AppEnum.ExeEntityType.isProperty)
{
if (!(reader[property.Name] is DBNull))
property.SetValue(entity, reader[property.Name], null);
}
}
}
reader.Close();
reader.Dispose();
}
return entity;
}
返回一个实体集合,类似上面的
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/// <summary>
/// 获取实体集合
/// </summary>
/// <typeparam name="TEntity">实体(泛型)</typeparam>
/// <param name="cmdText">命令</param>
/// <param name="commandType">命令类型</param>
/// <param name="exeEntityType">按属性/特性映射</param>
/// <param name="paramers">参数数组</param>
/// <returns>实体集合</returns>
public static IList<TEntity> GetEntityList<TEntity>(string cmdText, CommandType commandType, AppEnum.ExeEntityType exeEntityType, params DbParameter[] paramers) where TEntity : new()
{
IList<TEntity> entityList = new List<TEntity>();
using (IDataReader reader = DbHelper.CreateDataReader(cmdText, commandType, paramers))
{
while (reader.Read())
{
TEntity entity = new TEntity();
Type entityType = entity.GetType();
PropertyInfo[] propertyInfos = entityType.GetProperties();
foreach (PropertyInfo property in propertyInfos)
{
if (exeEntityType == AppEnum.ExeEntityType.isAttribute)
{
DataFieldAttribute datafieldAttribute = GetDataFieldAttribute(property);
if (datafieldAttribute == null)
throw new AssionException("AppEnum.ExeEntityType枚举为 isAttribute 时,实体类需要指定特性!");
if (!(reader[datafieldAttribute.FieldName] is DBNull))
property.SetValue(entity, reader[datafieldAttribute.FieldName], null);
}
else if (exeEntityType == AppEnum.ExeEntityType.isProperty)
{
if (!(reader[property.Name] is DBNull))
property.SetValue(entity, reader[property.Name], null);
}
}
entityList.Add(entity);
}
}
return entityList;
}
执行SQL实体映射操作,可以写INSERT、UPDATE、DELETE 操作,这样灵活些,抽时间再完成个自动映射生成SQL的,不过灵活性就差些了
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/// <summary>
/// 插入,更新,删除数据库实体
/// </summary>
/// <typeparam name="TEntity">实体(泛型)</typeparam>
/// <param name="cmdText">命令</param>
/// <param name="commandType">命令类型</param>
/// <param name="exeEntityType">按属性/特性映射</param>
/// <param name="entity">实体</param>
/// <returns>影响行数</returns>
public static int ExeEntity<TEntity>(string cmdText, CommandType commandType, AppEnum.ExeEntityType exeEntityType,TEntity entity) where TEntity : new()
{
Type entityType = entity.GetType();
PropertyInfo[] propertyInfos = entityType.GetProperties();
List<DbParameter> paramerList = new List<DbParameter>();
foreach (PropertyInfo property in propertyInfos)
{
if (exeEntityType == AppEnum.ExeEntityType.isAttribute)
{
DataFieldAttribute datafieldAttribute = GetDataFieldAttribute(property);
if (datafieldAttribute == null)
throw new AssionException("AppEnum.ExeEntityType枚举为 isAttribute 时,实体类需要指定特性!");
object oval=property.GetValue(entity,null);
oval = oval == null ? DBNull.Value : oval;
paramerList.Add(DbHelper.CreateParamer("@" + datafieldAttribute.FieldName, oval));
}
else if (exeEntityType == AppEnum.ExeEntityType.isProperty)
{
object oval = property.GetValue(entity, null);
oval = oval == null ? DBNull.Value : oval;
paramerList.Add(DbHelper.CreateParamer("@" + property.Name, oval));
}
}
int retval=DbHelper.ExecuteNonQuery(cmdText, commandType, paramerList.ToArray());
return retval;
}
下面是字段的自定义特性和获取特性的代码:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/// <summary>
/// 自定义特性:映射数据库字段名
/// </summary>
[AttributeUsage(AttributeTargets.Struct|AttributeTargets.Property|AttributeTargets.Field)]
public class DataFieldAttribute:Attribute
{
private string _fieldName; //字段名
public string FieldName
{
get { return _fieldName; }
set { _fieldName = value; }
}
public DataFieldAttribute(string fieldName)
{
this._fieldName = fieldName;
}
}
/// <summary>
/// 获取DataFieldAttribute特性
/// </summary>
/// <param name="property">属性</param>
/// <returns>DataFieldAttribute</returns>
private static DataFieldAttribute GetDataFieldAttribute(PropertyInfo property)
{
object[] oArr=property.GetCustomAttributes(true);
for(int i=0;i<oArr.Length;i++)
{
if(oArr[i] is DataFieldAttribute)
return (DataFieldAttribute)oArr[i];
}
return null;
}
使用示例:
首先实体加上特性:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
public class People
{
[PrimaryKey()]
[DataField("DbName")]
public string Name { get; set; }
[DataField("DbTel")]
public string tel { get; set; }
}
获取一个实体集合:
IList<People> peopleList = ExecuteEntity.GetEntityList<People>("SELECT DbName,DbTel FROM Test", CommandType.Text, AppEnum.ExeEntityType.isAttribute, null);
向数据库插入实体数据:
ExecuteEntity.ExeEntity<People>("INSERT INTO Test (DbName,DbTel) VALUES (@DbName,@DbTel)", CommandType.Text, AppEnum.ExeEntityType.isAttribute, people);
最后再附上一个基础的数据库操作类:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/// <summary>
/// 通用数据库帮助类
/// </summary>
public static class DbHelper
{
#region 连接配置读取
/// <summary>
/// 数据库类型
/// </summary>
private static readonly string dataProvider = ConfigurationManager.ConnectionStrings["ConnectionString"].ProviderName;
/// <summary>
/// 反射数据库类型
/// </summary>
private static readonly DbProviderFactory dataFactory = DbProviderFactories.GetFactory(dataProvider);
/// <summary>
/// 数据库连接字符串
/// </summary>
private static readonly string connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
#endregion
#region 连接命令
/// <summary>
/// 创建连接
/// </summary>
/// <returns>dbconnection</returns>
public static DbConnection CreateConnection()
{
DbConnection dbConn = dataFactory.CreateConnection();
dbConn.ConnectionString = connectionString;
return dbConn;
}
/// <summary>
/// 创建命令
/// </summary>
/// <param name="cmdText">命令</param>
/// <param name="commandType">命令类型</param>
/// <param name="paramers">参数数组</param>
/// <returns>command</returns>
public static DbCommand CreateCommand(string cmdText,CommandType commandType,params DbParameter[] paramers)
{
DbConnection dbConn=CreateConnection();
dbConn.Open();
DbCommand dbCmd = dataFactory.CreateCommand();
dbCmd.Connection = dbConn;
dbCmd.CommandText = cmdText;
dbCmd.CommandType = commandType;
if(paramers!=null)
dbCmd.Parameters.AddRange(paramers);
return dbCmd;
}
#endregion
#region 数据执行方法
/// <summary>
/// 创建带参数的只读器
/// </summary>
/// <param name="cmdText">命令</param>
/// <param name="commandType">命令类型</param>
/// <param name="paramers">参数数组</param>
/// <returns>reader</returns>
public static DbDataReader CreateDataReader(string cmdText, CommandType commandType, params DbParameter[] paramers)
{
DbDataReader reader = null;
reader = CreateCommand(cmdText, commandType, paramers).ExecuteReader(CommandBehavior.CloseConnection);
return reader;
}
/// <summary>
/// 创建无参数的只读器
/// </summary>
/// <param name="cmdText">命令</param>
/// <param name="commandType">命令类型</param>
/// <returns>reader</returns>
public static DbDataReader CreateDataReader(string cmdText, CommandType commandType)
{
DbDataReader reader = null;
reader = CreateCommand(cmdText, commandType, null).ExecuteReader(CommandBehavior.CloseConnection);
return reader;
}
/// <summary>
/// 执行一个带参数的SQL/存储过程
/// </summary>
/// <param name="cmdText">命令</param>
/// <param name="commandType">命令类型</param>
/// <param name="paramers">参数数组</param>
/// <returns>影响行数</returns>
public static int ExecuteNonQuery(string cmdText, CommandType commandType, params DbParameter[] paramers)
{
int retval = CreateCommand(cmdText, commandType, paramers).ExecuteNonQuery();
return retval;
}
/// <summary>
/// 执行一个不带参数的SQL/存储过程
/// </summary>
/// <param name="cmdText">命令</param>
/// <param name="commandType">命令类型</param>
/// <returns>影响行数</returns>
public static int ExecuteNonQuery(string cmdText, CommandType commandType)
{
int retval = CreateCommand(cmdText, commandType, null).ExecuteNonQuery();
return retval;
}
/// <summary>
/// 执行一个带参数的SQL/存储过程有事务的
/// </summary>
/// <param name="tran">事务</param>
/// <param name="cmdText">命令</param>
/// <param name="commmandType">命令类型</param>
/// <param name="paramers">参数数组</param>
/// <returns>影响行数</returns>
public static int ExecuteNonQuery(DbTransaction tran,string cmdText,CommandType commmandType,params DbParameter[] paramers)
{
DbConnection dbConn = tran.Connection;
DbCommand dbCmd=dataFactory.CreateCommand();
dbCmd.Connection=dbConn;
dbCmd.CommandType=commmandType;
dbCmd.CommandText=cmdText;
dbCmd.Parameters.AddRange(paramers);
dbCmd.Transaction = tran;
int retval=dbCmd.ExecuteNonQuery();
return retval;
}
/// <summary>
/// 执行一个无参数的SQL/存储过程有事务的
/// </summary>
/// <param name="tran">事务</param>
/// <param name="cmdText">命令</param>
/// <param name="commmandType">命令类型</param>
/// <returns>影响行数</returns>
public static int ExecuteNonQuery(DbTransaction tran, string cmdText, CommandType commmandType)
{
DbConnection dbConn = tran.Connection;
DbCommand dbCmd = dataFactory.CreateCommand();
dbCmd.Connection = dbConn;
dbCmd.CommandType = commmandType;
dbCmd.CommandText = cmdText;
dbCmd.Transaction = tran;
int retval = dbCmd.ExecuteNonQuery();
return retval;
}
/// <summary>
/// 执行一个带参数的SQL/存储过程返回首行首列
/// </summary>
/// <param name="cmdText">命令</param>
/// <param name="commandType">命令类型</param>
/// <param name="paramers">参数数组</param>
/// <returns>值</returns>
public static object ExecuteScalar(string cmdText, CommandType commandType, params DbParameter[] paramers)
{
object retval = CreateCommand(cmdText,commandType,paramers).ExecuteScalar();
return retval;
}
/// <summary>
/// 执行一个无参数的SQL/存储过程返回首行首列
/// </summary>
/// <param name="cmdText">命令</param>
/// <param name="commandType">命令类型</param>
/// <param name="paramers">参数数组</param>
/// <returns>值</returns>
public static object ExecuteScalar(string cmdText, CommandType commandType)
{
object retval = CreateCommand(cmdText,commandType,null).ExecuteScalar();
return retval;
}
#endregion
#region 创建参数方法
/// <summary>
/// 创建参数
/// </summary>
/// <param name="pName">参数名</param>
/// <param name="pValue">参数值</param>
/// <returns>参数</returns>
public static DbParameter CreateParamer(string pName, object pValue)
{
DbParameter paramer = dataFactory.CreateParameter();
paramer.ParameterName = pName;
paramer.Value = pValue;
return paramer;
}
/// <summary>
/// 创建参数
/// </summary>
/// <param name="pName">参数名</param>
/// <param name="pValue">参数值</param>
/// <param name="pType">参数类型</param>
/// <returns>参数</returns>
public static DbParameter CreateParamer(string pName, object pValue, DbType pType)
{
DbParameter paramer = dataFactory.CreateParameter();
paramer.ParameterName = pName;
paramer.Value = pValue;
paramer.DbType = pType;
return paramer;
}
/// <summary>
/// 创建参数
/// </summary>
/// <param name="pName">参数名</param>
/// <param name="pValue">参数值</param>
/// <param name="pType">参数类型</param>
/// <param name="pSize">长度</param>
/// <returns>参数</returns>
public static DbParameter CreateParamer(string pName, object pValue, DbType pType, int pSize)
{
DbParameter paramer = dataFactory.CreateParameter();
paramer.ParameterName = pName;
paramer.Value = pValue;
paramer.DbType = pType;
paramer.Size = pSize;
return paramer;
}
#endregion
}
暂时就实现了这么多,继续开发,感觉一个强大的数据库操作类就是要大,要多,要全,要爆力!