c#利用反射+特性实现简单的实体映射数据库操作类(表与类的映射)
时间:2011-04-23 来源:阿 & 文
开始之前首先需要了解 特性Attribute; 说穿了特性也就是一些声明信息;我们在运行的时候可以用反射获取这些声明;
所想我们试想下;我们新建一个类用来存放数据库表中的信息; 那我们是不是需要在该类中有专门存放该表字段信息的类的字段呢?(这里说的是存放表中的全部字段信息)
在想想下,描述一个数据库字段需要哪些信息; 二类中字段可以满足哪些信息吗! 所以我们需要对该字段进行描述 ,比如说字段名称呀,字段数据类型呀,字段数据类型长度呀,还有有是否为主键呀?
我也是初学者 我这里只是说最基础的
建立特性类;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace DataTransfer
{
[AttributeUsage(AttributeTargets.Property,AllowMultiple=false,Inherited=false)]
public class FieldAttribute:Attribute
{
private string _Fields;
/// <summary>
/// 字段名称
/// </summary>
public string Fields
{
get { return _Fields; }
}
private DbType _Dbtype;
/// <summary>
/// 字段类型
/// </summary>
public DbType Dbtype
{
get { return _Dbtype; }
}
private int _ValueLength;
/// <summary>
/// 字段值长度
/// </summary>
public int ValueLength
{
get { return _ValueLength; }
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="fields"> 字段名</param>
/// <param name="types"> 字段类型</param>
/// <param name="i"> 字段值长度</param>
public FieldAttribute(string fields,DbType types, int i)
{
_Fields=fields;
_Dbtype=types;
_ValueLength=i;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DataTransfer
{
[AttributeUsage(AttributeTargets.Class,AllowMultiple=false,Inherited=false)]
public class TableAttribute:Attribute
{
private string _TableName;
/// <summary>
/// 映射的表名
/// </summary>
public string TableName
{
get { return _TableName; }
}
/// <summary>
/// 定位函数映射表名;
/// </summary>
/// <param name="table"></param>
public TableAttribute(string table)
{
_TableName = table;
}
}
}
这里是建立的2个特性类; 建立与表映射的类TableAttribute 外加与字段映射的类 FieldAttribute;
建立联系的类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace DataTransfer
{
[Table("Consumers")]// 这里[Table("Consumers")] 或者 [TableAttribute("Consumers")] 是一样的效果
public class UserInf
{
private string _UserID;
/// <summary>
/// 登陆ID
/// </summary>
[Field("ConsumerID",DbType.String,12)]
public string U_UserID
{
get { return _UserID; }
set { _UserID = value; }
}
private string _Psw;
/// <summary>
/// 登陆密码
/// </summary>
[Field("ConsumerPwd",DbType.String,12)]
public string U_Psw
{
get { return _Psw; }
set { _Psw = value; }
}
private string _UserName;
/// <summary>
/// 用户别称
/// </summary>
[Field("ConsumerName",DbType.String,50)]
public string U_UserName
{
get { return _UserName; }
set { _UserName = value; }
}
private string _City;
/// <summary>
/// 所住城市
/// </summary>
[Field("UserCity",DbType.String,50)]
public string U_City
{
get { return _City; }
set { _City = value; }
}
private int _Popedom;
/// <summary>
/// 权限
/// </summary>
[Field("popedom", DbType.Int32, 0)]
public int U_Popedom
{
get { return _Popedom; }
set { _Popedom = value; }
}
private DateTime _AddDataTime;
/// <summary>
/// 注册时间
/// </summary>
[Field("addDataTime",DbType.Date,0)]
public DateTime U_AddDataTime
{
get { return _AddDataTime; }
set { _AddDataTime = value; }
}
private int _Sex;
/// <summary>
/// 性别
/// </summary>
[Field("Sex",DbType.Int32,0)]
public int U_Sex
{
get { return _Sex; }
set { _Sex = value; }
}
private int _BirthTime;
/// <summary>
/// 出身日期;
/// </summary>
[Field("BirthTime", DbType.String, 9)]
public int U_BirthTime
{
get { return _BirthTime; }
set { _BirthTime = value; }
}
}
}
在aspx页面中
UserInf userss = new UserInf();
userss.U_UserID = "aw12311";
userss.U_Psw = "123";
userss.U_UserName = "aw";
userss.U_City = "武汉";
userss.U_Popedom = 1;
userss.U_Sex = 1;
userss.U_BirthTime = 19900114;
userss.U_AddDataTime = DateTime.Now;
///这里先让你查看字段描述;
查看表的特性;
Type userAttu = userss.GetType();
TableAttribute tables = (TableAttribute)userAttu.GetCustomAttributes(false)[0];//这里我在TableAttribute个类中写的是不容许多个描述,所以只有一个实例;
Response.Write(tables.TableName);
//查看类中字段的描述
PropertyInfo[] info = userAttu.GetProperties();
foreach (PropertyInfo prs in info)
{
Response.Write("--------------------------------</br>");
object[] attu = prs.GetCustomAttributes(false);
object obj = prs.GetGetMethod().Invoke(userss,null);//取出当前描述字段的值
Response.Write(prs.Name +"|"+ obj +"</br>");//这里显示类中字段的名称 与值
foreach(Attribute abute in attu )
{
if (abute is FieldAttribute)
{
FieldAttribute column = abute as FieldAttribute;
Response.Write(column.Fields +"</br>");
Response.Write(column.Dbtype + "</br>");
Response.Write(column.ValueLength + "</br>");
}
}
}
接着在 c# 中 传递帮他了的类拼接处查询字符串;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Reflection;
namespace DataTransfer
{
public class DateIsTableAttribute<T>
{
public string insertDate(T types)
{
string cmdtxt = "insert into ";
string cmdparVar = null;
Type userAttu = types.GetType();
TableAttribute tables = (TableAttribute )userAttu.GetCustomAttributes(false)[0];
cmdtxt += tables.TableName + "(";
PropertyInfo[] info = userAttu.GetProperties();
foreach (PropertyInfo prs in info)
{
object[] attu = prs.GetCustomAttributes(false);
foreach (Attribute abute in attu)
{
if (abute is FieldAttribute)
{
FieldAttribute midle = abute as FieldAttribute;
cmdtxt += midle.Fields + ",";
object obj = prs.GetGetMethod().Invoke(types,null);
if (midle.Dbtype == DbType.Int32)
cmdparVar += obj + ",";
else
cmdparVar+="'"+obj +"',";
}
}
}
cmdparVar = cmdparVar.Substring(0, cmdparVar.Length - 1);
cmdtxt = cmdtxt.Substring(0, cmdtxt.Length - 1) + ")";
cmdtxt += "values(" + cmdparVar + ")";
return cmdtxt;
}
}
}
然后再aspx 中的页面调用该方法
DateIsTableAttribute<UserInf> t = new DateIsTableAttribute<UserInf>();
///此处的userss 是上面实例化并赋值的userss;
Response.Write(" </br>" + t.insertDate(userss));
//这样你就会看到拼接完成的 插入字符串;
这只是思路 当我们字段插入字符串后那对数据库的插入我们就应该是小意思了吧! 同理我们可以做出响应的修改删除;
当我们需要插入并一张表的时候,或者修改等 , 那我们只需要新建一个加特征的与我们需要映射的表就好了其他都不需要改了;当我们吧那些插入 修改 删除 都包装在一起 , 那我们就可以实现自动化了 ,我们唯一需要做的就是怎样去建立类与数据库的映射就好了!;