欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#中将DataTable转化成List的方法解析

程序员文章站 2022-03-10 14:31:25
前言 通常在dal层我们都需要把datatable转换为list让调用者尽可能的好用,尽量的不用关心数据库的字段等,所以我们一般传过去的都是list&l...

前言

通常在dal层我们都需要把datatable转换为list<t>让调用者尽可能的好用,尽量的不用关心数据库的字段等,所以我们一般传过去的都是list<t>而不是datatable。

泛型的好处: 它为使用c#语言编写面向对象程序增加了极大的效力和灵活性。不会强行对值类型进行装箱和拆箱,或对引用类型进行。当涉及到两者之间的转换时,就显得有些较为繁琐。这个其中的问题主要在两者的存储方式,datatable的存储方式采用一种二维表的方式进行数据的存储操作,datatable表示内存中数据的一个表。在list集合中,list的本质就是一个数组,则采用一种线性结构对数据进行存储。

在转换过程中,主要的问题在于不同类型的处理上,主要分为值类型和引用类型两大类。

c#中值类型总是含有相应该类型的一个值,指类型包含:简单类型(simple types ),结构类型(struct types),枚举类型(enumeration types)。

  • 简单类型包含:整型,布尔型,字符型 (整型的一种特殊情况),浮点型,小数型。
  • 整型包含: sbyte byteshortushortintuintlongulong char
  • 引用类型:引用类型不存储它们所代表的实际数据,但它们存储实际数据的引用。主要包含:对象类型,类类 型,接口,代表元,字符串类型,数组。

现提供转换的代码,仅供参考:

1.类型枚举:

 /// <summary>
 /// 类型枚举
 /// </summary>
 private enum modeltype
 {
 //值类型
 struct,
 enum,
 //引用类型
 string,
 object,
 else
 }


 private static modeltype getmodeltype(type modeltype)
 {
 //值类型
 if (modeltype.isenum)
 {
 return modeltype.enum;
 }
 //值类型
 if (modeltype.isvaluetype)
 {
 return modeltype.struct;
 }
 //引用类型 特殊类型处理
 if (modeltype == typeof(string))
 {
 return modeltype.string;
 }
 //引用类型 特殊类型处理
 return modeltype == typeof(object) ? modeltype.object : modeltype.else;
 }

2.具体的转换操作方法:

 /// <summary>
 /// datatable转换为list<t>集合
 /// </summary>
 /// <typeparam name="t"></typeparam>
 /// <param name="table"></param>
 /// <returns></returns>
 public static list<t> datatabletolist<t>(datatable table)
 {
 var list = new list<t>();
 foreach (datarow item in table.rows)
 {
 list.add(datarowtomodel<t>(item));
 }
 return list;
 }

 public static t datarowtomodel<t>(datarow row)
 {
 t model;
 var type = typeof(t);
 var modeltype = getmodeltype(type);
 switch (modeltype)
 {
 //值类型
 case modeltype.struct:
 {
 model = default(t);
 if (row[0] != null)
 model = (t)row[0];
 }
 break;
 //值类型
 case modeltype.enum:
 {
 model = default(t);
 if (row[0] != null)
 {
 var fitype = row[0].gettype();
 if (fitype == typeof(int))
 {
 model = (t)row[0];
 }
 else if (fitype == typeof(string))
 {
 model = (t)enum.parse(typeof(t), row[0].tostring());
 }
 }
 }
 break;
 //引用类型 c#对string也当做值类型处理
 case modeltype.string:
 {
 model = default(t);
 if (row[0] != null)
 model = (t)row[0];
 }
 break;
 //引用类型 直接返回第一行第一列的值
 case modeltype.object:
 {
 model = default(t);
 if (row[0] != null)
 model = (t)row[0];
 }
 break;
 //引用类型
 case modeltype.else:
 {
 //引用类型 必须对泛型实例化
 model = activator.createinstance<t>();
 //获取model中的属性
 var modelpropertyinfos = type.getproperties();
 //遍历model每一个属性并赋值datarow对应的列
 foreach (var pi in modelpropertyinfos)
 {
 //获取属性名称
 var name = pi.name;
 if (!row.table.columns.contains(name) || row[name] == null) continue;
 var pitype = getmodeltype(pi.propertytype);
 switch (pitype)
 {
 case modeltype.struct:
  {
  var value = convert.changetype(row[name], pi.propertytype);
  pi.setvalue(model, value, null);
  }
  break;
 case modeltype.enum:
  {
  var fitype = row[0].gettype();
  if (fitype == typeof(int))
  {
  pi.setvalue(model, row[name], null);
  }
  else if (fitype == typeof(string))
  {
  var value = (t)enum.parse(typeof(t), row[name].tostring());
  if (value != null)
  pi.setvalue(model, value, null);
  }
  }
  break;
 case modeltype.string:
  {
  var value = convert.changetype(row[name], pi.propertytype);
  pi.setvalue(model, value, null);
  }
  break;
 case modeltype.object:
  {
  pi.setvalue(model, row[name], null);
  }
  break;
 case modeltype.else:
  throw new exception("不支持该类型转换");
 default:
  throw new exception("未知类型");
 }
 }
 }
 break;
 default:
 model = default(t);
 break;
 }
 return model;
 }

总结

以上的操作中,对不同类型有对应的处理方式。好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。