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