在项目中经常需要用到DataSet来存放数据,但是一直觉得从数据集中获取数据使用是一件很难受的事情,特别是当需要用到强类型数据的时候,就想到了动手写个方法来实现。
/// <summary>
/// 将数据集强类型化
/// </summary>
/// <typeparam name="T">转换类型</typeparam>
/// <param name="dataSet">数据源</param>
/// <param name="tableIndex">需要转换表的索引</param>
/// <returns>泛型集合</returns>
public static IList<T> ToList<T>(this DataSet dataSet, int tableIndex)
{
//确认参数有效
if (dataSet == null || dataSet.Tables.Count <= 0 || tableIndex < 0)
return null;
DataTable dt = dataSet.Tables[tableIndex];
IList<T> list = new List<T>();
for (int i = 0; i < dt.Rows.Count; i++)
{
//创建泛型对象
T _t = Activator.CreateInstance<T>();
//获取对象所有属性
PropertyInfo[] propertyInfo = _t.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
for (int j = 0; j < dt.Columns.Count; j++)
{
foreach (PropertyInfo info in propertyInfo)
{
//属性名称和列名相同时赋值
if (dt.Columns[j].ColumnName.ToUpper().Equals(info.Name.ToUpper()))
{
if (dt.Rows[i][j] != DBNull.Value)
{
info.SetValue(_t, dt.Rows[i][j].ConvertDataTo(info.PropertyType), null);
}
else
{
info.SetValue(_t, null, null);
}
break;
}
}
}
list.Add(_t);
}
return list;
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
在需要给属性赋值的时候,为了避免数据集中的字段名与用户定义的Model属性名一致而类型不一致的问题,我又写了个方法,用来把对象进行类型转换:
public static object ConvertDataTo(this object obj,Type type)
{
if (obj.GetType().Equals(type))
{
return obj;
}
else
{
try
{
if (type == typeof(string)) { return obj.ToString(); }
MethodInfo parseMethod = null;
foreach (MethodInfo mi in type.GetMethods(BindingFlags.Static | BindingFlags.Public))
{
if (mi.Name == "Parse" && mi.GetParameters().Length == 1)
{ parseMethod = mi; break; }
}
if (parseMethod == null)
{
return null;
}
return parseMethod.Invoke(null, new object[] { obj });
}
catch
{
return null;
throw;
}
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
其实这么写是比较偷懒的写法,用了这么多反射, 于是想到做一下性能测试,我建的MVC项目,看一下测试结果:
public ActionResult Index()
{
DataSet ds = new DataSet();
DataTable dt = new DataTable();
dt.Columns.Add("resourcename1", typeof(string));
dt.Columns.Add("resourcename2", typeof(string));
dt.Columns.Add("resourcename3", typeof(string));
dt.Columns.Add("resourcename4", typeof(string));
dt.Columns.Add("resourcename5", typeof(string));
dt.Columns.Add("fitsex1", typeof(int));
dt.Columns.Add("fitsex2", typeof(int));
dt.Columns.Add("fitsex3", typeof(int));
dt.Columns.Add("fitsex4", typeof(int));
dt.Columns.Add("fitsex5", typeof(int));
for (int i = 0; i < 5000; i++)
{
DataRow row = dt.NewRow();
row[0] = "王虎" + i.ToString();
row[1] = "王虎" + i.ToString();
row[2] = "王虎" + i.ToString();
row[3] = "王虎" + i.ToString();
row[4] = "王虎" + i.ToString();
row[5] = i;
row[6] = i;
row[7] = i;
row[8] = i;
row[9] = i;
dt.Rows.Add(row);
}
ds.Tables.Add(dt);
var watch = new Stopwatch();
watch.Start();
var ModelList = ds.ToList<Model_Resource>(0);
watch.Stop();
ViewData["Message"] = string.Format("ModelList.count={0},Elapsed Milliseconds:{1}", ModelList.Count.ToString(),watch.ElapsedMilliseconds.ToString());
return View();
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
我使用的类定义如下:
/// <summary>
/// 实体类Resource 。(属性说明自动提取数据库字段的描述信息)
/// </summary>
[Serializable]
public class Model_Resource
{
public Model_Resource()
{ }
#region Model
/// <summary>
/// 资源标准名称
/// </summary>
public string ResourceName1
{
get;
set;
}
/// <summary>
/// 资源标准名称
/// </summary>
public string ResourceName2
{
get;
set;
}
/// <summary>
/// 资源标准名称
/// </summary>
public string ResourceName3
{
get;
set;
}
/// <summary>
/// 资源标准名称
/// </summary>
public string ResourceName4
{
get;
set;
}
/// <summary>
/// 资源标准名称
/// </summary>
public string ResourceName5
{
get;
set;
}
/// <summary>
/// 适合的性别 1 男 2 女 3 均可
/// </summary>
public string FitSex1
{
get;
set;
}
/// <summary>
/// 适合的性别 1 男 2 女 3 均可
/// </summary>
public string FitSex2
{
get;
set;
}
/// <summary>
/// 适合的性别 1 男 2 女 3 均可
/// </summary>
public string FitSex3
{
get;
set;
}
/// <summary>
/// 适合的性别 1 男 2 女 3 均可
/// </summary>
public string FitSex4
{
get;
set;
}
/// <summary>
/// 适合的性别 1 男 2 女 3 均可
/// </summary>
public string FitSex5
{
get;
set;
}
#endregion Model
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
看一下测试结果:
注:
性能上还可以通过缓存等机制优化一下,不过这方面已经有一些大牛做过了,以后有时间可以加进去。
原文链接:http://www.cnblogs.com/wbpmrck/archive/2011/04/12/2013730.html
【编辑推荐】