Net特性与反射 DEMO
对于特性与反射的一些基本知识可以参考MSDN:http://msdn.microsoft.com/zh-cn/library/vstudio/ms173183.aspx
下面利用反射与特性做了一个关于实现DataTable与实体之间的相互转化的Demo.
实体类 Author:
public partial class Author
{
public Author()
{ }
#region Model
private int _id;
private string _title;
private string _content;
private string _email;
private string _sex;
/// <summary>
///
/// </summary>
[DataFiled("Id", SqlDbType.Int)]
public int Id
{
set { _id = value; }
get { return _id; }
}
/// <summary>
///
/// </summary>
[DataFiled("Title", SqlDbType.VarChar)]
public string Title
{
set { _title = value; }
get { return _title; }
}
/// <summary>
///
/// </summary>
[DataFiled("Content", SqlDbType.VarChar)]
public string Content
{
set { _content = value; }
get { return _content; }
}
/// <summary>
///
/// </summary>
[DataFiled("Email", SqlDbType.VarChar)]
public string Email
{
set { _email = value; }
get { return _email; }
}
/// <summary>
///
/// </summary>
[DataFiled("Sex", SqlDbType.VarChar)]
public string Sex
{
set { _sex = value; }
get { return _sex; }
}
#endregion Model
}
自定义特性类DataFiledAttribute和NoDataFiledAttribute类:
[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
public class DataFiledAttribute : Attribute
{
private string name;
private SqlDbType paramType;
private int size;
/// <summary>
///
/// </summary>
public string FieldName
{
get { return this.name == null ? string.Empty : this.name; }
set { this.name = value; }
}
public SqlDbType SqlDbType
{
get { return this.paramType; }
set { this.paramType = value; }
}
public int Size
{
get { return this.size; }
set { this.size = value; }
}
public bool IsSizeDefined
{
get { return size != 0; }
}
public DataFiledAttribute(string strFieldName, SqlDbType sdtSqlDbType, int iSize)
{
this.name = strFieldName;
this.paramType = sdtSqlDbType;
this.size = iSize;
}
public DataFiledAttribute(string strFieldName, SqlDbType sdtSqlDbType)
: this(strFieldName, sdtSqlDbType, 0)
{
}
}
[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
public class NoDataFiledAttribute : Attribute { }
下面的是实现转化的类了
public class ModelHandler<T> { /// <summary> /// 实体列表转为DataTable 注意:使用本方法,须要实体中的每个属性必须添加DataFieldAttribute特性 /// </summary> /// <param name="objlist">实体列表</param> /// <returns>返回DataTable</returns> public static System.Data.DataTable Model2DataTable(List<T> objlist) { if (objlist.Count == 0) return null; DataTable dt = GeneratorDataTable(typeof(T)); foreach (T obj in objlist) { Type modelType = obj.GetType(); PropertyInfo[] properties = modelType.GetProperties(); DataRow dr = dt.NewRow(); for (int i = 0; i < properties.Length; i++) { dr[i] = properties[i].GetGetMethod().Invoke(obj, null); } dt.Rows.Add(dr); } return dt; } private static DataTable GeneratorDataTable(Type modelType) { //Type modelType = obj.GetType(); PropertyInfo[] properties = modelType.GetProperties(); DataFiledAttribute d = null; DataTable dt = new DataTable(); for (int i = 0; i < properties.Length; i++) { DataColumn dc = new DataColumn(); d = Attribute.GetCustomAttribute(properties[i], typeof(DataFiledAttribute)) as DataFiledAttribute; dc.ColumnName = d.FieldName; dc.DataType = typeof(string); dt.Columns.Add(dc); } return dt; } /// <summary> /// DataTable转为实体列表 /// </summary> /// <param name="dt"></param> /// <returns></returns> public static List<T> DataTable2Model(DataTable dt) { if (dt.Rows.Count == 0) { return null; } List<T> list = new List<T>(); foreach (DataRow dr in dt.Rows) { T obj = Activator.CreateInstance<T>(); foreach (DataColumn dc in dt.Columns) { PropertyInfo info = obj.GetType().GetProperty(dc.ColumnName); Type t = info.PropertyType; info.SetValue(obj, Convert.ChangeType(dr[dc], t), null); } list.Add(obj); } return list; } }
具体实现如下:
Author model = new Author(); model.Id = 1; model.Title = "test"; model.Content = null; List<Author> list = new List<Author>(); list.Add(model); DataTable dt = ModelHandler<Author>.Model2DataTable(list); List<Author> list1 = new List<Author>(); list1 = ModelHandler<Author>.DataTable2Model(dt);
查看一下结果: