C#中将DataTable转化成List的方法解析
前言
通常在DAL层我们都需要把DataTable转换为List<T>让调用者尽可能的好用,尽量的不用关心数据库的字段等,所以我们一般传过去的都是List<T>而不是DataTable。
泛型的好处:它为使用c#语言编写面向对象程序增加了极大的效力和灵活性。不会强行对值类型进行装箱和拆箱,或对引用类型进行。当涉及到两者之间的转换时,就显得有些较为繁琐。这个其中的问题主要在两者的存储方式,DataTable的存储方式采用一种二维表的方式进行数据的存储操作,DataTable表示内存中数据的一个表。在List集合中,List的本质就是一个数组,则采用一种线性结构对数据进行存储。
在转换过程中,主要的问题在于不同类型的处理上,主要分为值类型和引用类型两大类。
C#中值类型总是含有相应该类型的一个值,指类型包含:简单类型(Simpletypes),结构类型(structtypes),枚举类型(Enumerationtypes)。
- 简单类型包含:整型,布尔型,字符型(整型的一种特殊情况),浮点型,小数型。
- 整型包含:sbyte、byte、short、ushort、int、uint、long、ulong和char。
- 引用类型:引用类型不存储它们所代表的实际数据,但它们存储实际数据的引用。主要包含:对象类型,类类型,接口,代表元,字符串类型,数组。
现提供转换的代码,仅供参考:
1.类型枚举:
///<summary> ///类型枚举 ///</summary> privateenumModelType { //值类型 Struct, Enum, //引用类型 String, Object, Else } privatestaticModelTypeGetModelType(TypemodelType) { //值类型 if(modelType.IsEnum) { returnModelType.Enum; } //值类型 if(modelType.IsValueType) { returnModelType.Struct; } //引用类型特殊类型处理 if(modelType==typeof(string)) { returnModelType.String; } //引用类型特殊类型处理 returnmodelType==typeof(object)?ModelType.Object:ModelType.Else; }
2.具体的转换操作方法:
///<summary> ///datatable转换为List<T>集合 ///</summary> ///<typeparamname="T"></typeparam> ///<paramname="table"></param> ///<returns></returns> publicstaticList<T>DataTableToList<T>(DataTabletable) { varlist=newList<T>(); foreach(DataRowitemintable.Rows) { list.Add(DataRowToModel<T>(item)); } returnlist; } publicstaticTDataRowToModel<T>(DataRowrow) { Tmodel; vartype=typeof(T); varmodelType=GetModelType(type); switch(modelType) { //值类型 caseModelType.Struct: { model=default(T); if(row[0]!=null) model=(T)row[0]; } break; //值类型 caseModelType.Enum: { model=default(T); if(row[0]!=null) { varfiType=row[0].GetType(); if(fiType==typeof(int)) { model=(T)row[0]; } elseif(fiType==typeof(string)) { model=(T)Enum.Parse(typeof(T),row[0].ToString()); } } } break; //引用类型c#对string也当做值类型处理 caseModelType.String: { model=default(T); if(row[0]!=null) model=(T)row[0]; } break; //引用类型直接返回第一行第一列的值 caseModelType.Object: { model=default(T); if(row[0]!=null) model=(T)row[0]; } break; //引用类型 caseModelType.Else: { //引用类型必须对泛型实例化 model=Activator.CreateInstance<T>(); //获取model中的属性 varmodelPropertyInfos=type.GetProperties(); //遍历model每一个属性并赋值DataRow对应的列 foreach(varpiinmodelPropertyInfos) { //获取属性名称 varname=pi.Name; if(!row.Table.Columns.Contains(name)||row[name]==null)continue; varpiType=GetModelType(pi.PropertyType); switch(piType) { caseModelType.Struct: { varvalue=Convert.ChangeType(row[name],pi.PropertyType); pi.SetValue(model,value,null); } break; caseModelType.Enum: { varfiType=row[0].GetType(); if(fiType==typeof(int)) { pi.SetValue(model,row[name],null); } elseif(fiType==typeof(string)) { varvalue=(T)Enum.Parse(typeof(T),row[name].ToString()); if(value!=null) pi.SetValue(model,value,null); } } break; caseModelType.String: { varvalue=Convert.ChangeType(row[name],pi.PropertyType); pi.SetValue(model,value,null); } break; caseModelType.Object: { pi.SetValue(model,row[name],null); } break; caseModelType.Else: thrownewException("不支持该类型转换"); default: thrownewException("未知类型"); } } } break; default: model=default(T); break; } returnmodel; }
总结
以上的操作中,对不同类型有对应的处理方式。好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。