对于特性与反射的一些基本知识可以参考MSDN:
下面利用反射与特性做了一个关于实现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;
///
///
///
[DataFiled("Id", SqlDbType.Int)]
public int Id
{
set { _id = value; }
get { return _id; }
}
///
///
///
[DataFiled("Title", SqlDbType.VarChar)]
public string Title
{
set { _title = value; }
get { return _title; }
}
///
///
///
[DataFiled("Content", SqlDbType.VarChar)]
public string Content
{
set { _content = value; }
get { return _content; }
}
///
///
///
[DataFiled("Email", SqlDbType.VarChar)]
public string Email
{
set { _email = value; }
get { return _email; }
}
///
///
///
[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;
///
///
///
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{ /// /// 实体列表转为DataTable 注意:使用本方法,须要实体中的每个属性必须添加DataFieldAttribute特性 /// /// 实体列表 ///返回DataTable public static System.Data.DataTable Model2DataTable(Listobjlist) { 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; } /// /// DataTable转为实体列表 /// /// ///public static List DataTable2Model(DataTable dt) { if (dt.Rows.Count == 0) { return null; } List list = new List (); foreach (DataRow dr in dt.Rows) { T obj = Activator.CreateInstance (); 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; Listlist = new List (); list.Add(model); DataTable dt = ModelHandler .Model2DataTable(list); List list1 = new List (); list1 = ModelHandler .DataTable2Model(dt);
查看一下结果:
DataTable:
list<model>: