好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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

前言

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

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

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

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

简单类型包含:整型,布尔型,字符型 (整型的一种特殊情况),浮点型,小数型。 整型包含: sbyte 、 byte 、 short 、 ushort 、 int 、 uint 、 long 、 ulong 和 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;

}

总结

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

dy("nrwz");

查看更多关于C#中将DataTable转化成List<T>的方法解析的详细内容...

  阅读:52次