底层采用ADO.NET获取数据返回的数据类型为DataTable,把DataTable数据转换为类类型的泛型集合。在这过程中解决了采用泛型约束方式封装的方法中使用new关键字创建实例无法使用带参数的构造函数问题。实现代码如下:
DataTable数据转换为List实现代码
public class LoadDataHelper<T> where T : class,new() { public List<T> LoadListFromDataTable(DataTable dt) { DataView dv = dt.DefaultView; List<T> list = new List<T>(); for (int index = 0; index <= dv.Count - 1; index++) { //利用用非泛型的重载,构造了带参数的T的实例 T t = (T)System.Activator.CreateInstance(typeof(T), dv[index].Row); list.Add(t); } return list; } }
用到的一个类
[Serializable] //设置sessionState mode="StateServer",要求序列化 public class Recommend { /// <summary> /// 构造一个空的新的数据访问对象 /// </summary> /// <remarks></remarks> public Recommend() { } /// <summary> /// 推荐对象编号 /// </summary> public int ObjectId { get; set; } /// <summary> /// 推荐对象标题 /// </summary> public string ObjectTitle { get; set; } /// <summary> /// 推荐对象栏目编号 /// </summary> public int CategoryId { get; set; } /// <summary> /// 推荐对象父栏目编号 /// </summary> public int ParentId { get; set; } /// <summary> /// 推荐对象图片 /// </summary> public string ObjectImages { get; set; } /// <summary> /// 推荐对象链接 /// </summary> public string ObjectUrl { get; set; } /// <summary> /// 推荐对象描述 /// </summary> public string ObjectDes { get; set; } /// <summary> /// 推荐用户名 /// </summary> public string UserName { get; set; } /// <summary> /// 排序 /// </summary> public int Forder { get; set; } /// <summary> /// 推荐时间 /// </summary> public DateTime CreateTime { get; set; } /// <summary> /// 作者 /// </summary> public string ObjectAuthor { get; set; } /// <summary> /// 价格 /// </summary> public string ObjectPrice { get; set; } /// <summary> /// 构造一个数据访问对象,并将DataRow列的数据提取到对象的属性里 /// </summary> /// <remarks></remarks> public Recommend(DataRow row) { LoadFromRow(row); } /// <summary> /// 构造一个数据访问对象,并将DataRow列的数据提取到对象的属性里 /// </summary> /// <remarks></remarks> public void LoadFromRow(DataRow row) { this.ObjectId = row.Table.Columns.Contains("ObjectId") ? row["ObjectId"].Toint(0) : 0; this.ObjectTitle = row.Table.Columns.Contains("ObjectTitle") ? row["ObjectTitle"].Tostring() : ""; this.CategoryId = row.Table.Columns.Contains("CategoryId") ? row["CategoryId"].Toint(0) : 0; this.ParentId = row.Table.Columns.Contains("ParentId") ? row["ParentId"].Toint(0) : 0; string masterSite = ConfigurationManager.AppSettings["masterSite"].Tostring(); this.ObjectImages = row.Table.Columns.Contains("ObjectImages") ? masterSite.TrimEnd('/')+row["ObjectImages"].Tostring() : ""; this.ObjectUrl = row.Table.Columns.Contains("ObjectUrl") ? row["ObjectUrl"].Tostring() : ""; this.ObjectDes = row.Table.Columns.Contains("ObjectDes") ? row["ObjectDes"].Tostring() : ""; this.UserName = row.Table.Columns.Contains("UserName") ? row["UserName"].Tostring() : ""; this.Forder = row.Table.Columns.Contains("Forder") ? row["Forder"].Toint(0) : 0; this.ObjectAuthor = row.Table.Columns.Contains("ObjectAuthor") ? row["ObjectAuthor"].Tostring() : ""; this.ObjectPrice = row.Table.Columns.Contains("ObjectPrice") ? row["ObjectPrice"].Tostring() : ""; this.CreateTime = row.Table.Columns.Contains("CreateTime") ? row["CreateTime"].Todate() : DateTime.Now; } public struct JsonRecommend { public int State; public List<Model.Recommend> Rows; } }
方法调用
public List<Model.Recommend> GetRecommendByCategoryId(int categoryId) { StringBuilder sqlText = new StringBuilder(); sqlText.Append("select objectId,objectTitle,categoryId,parentId,objectImages,objectUrl,objectDes,userName,forder,createTime,objectAuthor,objectPrice from Fotomall_Recommend where categoryId=@categoryId order by objectId desc"); DbParameter[] param; param = new DbParameter[] { FotosayMall.CreateInDbParameter("@categoryId", DbType.Int32,categoryId) }; DataTable adminList = FotosayMall.ExecuteQueryTable(CommandType.Text, sqlText.ToString(), param); LoadDataHelper<Model.Recommend> a = new LoadDataHelper<Model.Recommend>(); return a.LoadListFromDataTable(adminList); //return LoadListFromDataTable(adminList.DefaultView); }
方法二
//获取用户列表 public static List<Model.User> GetUsers() { List<Model.User> Users = new List<Model.User>(); string sql = string.Format("SELECT * FROM [dbo].[User]"); DataSet ds = SqlHelper.ExecuteDataset(connectionString, CommandType.Text, sql); if (ds != null && ds.Tables.Count > 0) { foreach (DataTable dt in ds.Tables) { foreach (DataRow dr in dt.Rows) { Model.User user = new Model.User(); user.UserID = Convert.ToInt32(dr["UserID"]); user.UserName = dr["UserName"].ToString(); user.Password = dr["Password"].ToString(); user.Discribe = dr["Discribe"].ToString(); user.SubmitTime = Convert.ToDateTime(dr["SubmitTime"]); Users.Add(user); } } } return Users; }
方法二的重构以及扩展(反射的应用)
public static class DataTableHelper<T> where T:class { /// <summary> /// DataTable To List /// </summary> /// <typeparam name="T">要转化成的类型</typeparam> /// <param name="dt">数据表</param> /// <returns>List</returns> public static List<T> DataTableToList(DataTable dt) { var list = new List<T>(); Type t = typeof(T); var plist = new List<PropertyInfo>(typeof(T).GetProperties()); foreach (DataRow item in dt.Rows) { T s = System.Activator.CreateInstance<T>(); for (int i = 0; i < dt.Columns.Count; i++) { PropertyInfo info = plist.Find(p => p.Name == dt.Columns[i].ColumnName); if (info != null) { if (!Convert.IsDBNull(item[i])) { info.SetValue(s, item[i], null); } } } list.Add(s); } return list; } /// <summary> /// 转换datatable(包含一条数据)成类型(T)对象实体 /// </summary> /// <param name="dt"></param> /// <returns></returns> public static T DataTableToModel(DataTable dt) { T s = System.Activator.CreateInstance<T>(); Type t = typeof(T); var plist = new List<PropertyInfo>(typeof(T).GetProperties()); if (dt.Rows.Count==1) { foreach (DataRow item in dt.Rows) { for (int i = 0; i < dt.Columns.Count; i++) { PropertyInfo info = plist.Find(p => p.Name == dt.Columns[i].ColumnName); if (info != null) { if (!Convert.IsDBNull(item[i])) { info.SetValue(s, item[i], null); } } } } } return s; } }
注意:方法二的重构后的方式要求类的属性和数据库表的字段名相同或者与查询生成的表的列名相同。