这是数据库开发中经常遇到的问题,当然,这可以用现成的ORM框架来解决,但有些时候,如果DataSet/DataTable是第三方接口返回的,ORM就不方便了,还得自己处理。

反射自然必不可少的,另外考虑到DataTable中的ColumnName通常与Model的PropertyName并不严格对应,可以用Attribute来记录这种映射关系。

步骤1:先创建一个DataFieldAttribute类

  1. using System;
  2.  
  3. namespace Jimmy.ORM
  4. {
  5. [AttributeUsage(AttributeTargets.Property)]
  6. public sealed class DataFieldAttribute:Attribute
  7. {
  8. /// <summary>
  9. /// 表对应的字段名
  10. /// </summary>
  11. public string ColumnName { set; get; }
  12.  
  13. public DataFieldAttribute(string columnName)
  14. {
  15. ColumnName = columnName;
  16. }
  17. }
  18. }

步骤2:在Model/Entity的Class成员上,应用DataField特性,参见下面的代码:

  1. using System;
  2.  
  3. namespace Jimmy.ORM.Entity
  4. {
  5. [Serializable]
  6. public class ProductEntity : DataEntityBase
  7. {
  8.  
  9. [DataField("PRODUCT_NO")]
  10. public string ProductNo { set; get; }
  11.  
  12. [DataField("PRODUCT_ID")]
  13. public int ProductId { set; get; }
  14.  
  15. [DataField("PRODUCT_NAME")]
  16. public string ProductName { set; get; }
  17.  
  18. public override string ToString()
  19. {
  20. return string.Format("ProductNo:{1}{0}ProductId:{2}{0}ProductName:{3}", Environment.NewLine, ProductNo,
  21. ProductId, ProductName);
  22. }
  23. }
  24. }

步骤3:该反射出场了,为了方便起见,封装了一个DataConvert类

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.Reflection;
  5.  
  6. namespace Jimmy.ORM
  7. {
  8. /// <summary>
  9. /// 将DataRow/DataTable转换成Entity/Entity列表
  10. /// </summary>
  11. public static class DataConvert<T> where T : DataEntityBase, new()
  12. {
  13. /// <summary>
  14. /// 将DataRow行转换成Entity
  15. /// </summary>
  16. /// <param name="dr"></param>
  17. /// <returns></returns>
  18. public static T ToEntity(DataRow dr)
  19. {
  20. T entity = new T();
  21. Type info = typeof(T);
  22. var members = info.GetMembers();
  23. foreach (var mi in members)
  24. {
  25. if (mi.MemberType == MemberTypes.Property)
  26. {
  27. //读取属性上的DataField特性
  28. object[] attributes = mi.GetCustomAttributes(typeof(DataFieldAttribute), true);
  29. foreach (var attr in attributes)
  30. {
  31. var dataFieldAttr = attr as DataFieldAttribute;
  32. if (dataFieldAttr != null)
  33. {
  34. var propInfo = info.GetProperty(mi.Name);
  35. if (dr.Table.Columns.Contains(dataFieldAttr.ColumnName))
  36. {
  37. //根据ColumnName,将dr中的相对字段赋值给Entity属性
  38. propInfo.SetValue(entity,
  39. Convert.ChangeType(dr[dataFieldAttr.ColumnName], propInfo.PropertyType),
  40. null);
  41. }
  42.  
  43. }
  44. }
  45. }
  46. }
  47. return entity;
  48. }
  49.  
  50. /// <summary>
  51. /// 将DataTable转换成Entity列表
  52. /// </summary>
  53. /// <param name="dt"></param>
  54. /// <returns></returns>
  55. public static List<T> ToList(DataTable dt)
  56. {
  57. List<T> list = new List<T>(dt.Rows.Count);
  58. foreach (DataRow dr in dt.Rows)
  59. {
  60. list.Add(ToEntity(dr));
  61. }
  62. return list;
  63. }
  64. }
  65. }

步骤4:测试

  1. using System;
  2. using System.Data;
  3. using Jimmy.ORM.Entity;
  4.  
  5. namespace Jimmy.ORM.Test
  6. {
  7. class Program
  8. {
  9. static void Main()
  10. {
  11. DataTable dt = new DataTable();
  12. dt.Columns.Add("PRODUCT_NO");
  13. dt.Columns.Add("PRODUCT_ID");
  14. dt.Columns.Add("PRODUCT_NAME");
  15.  
  16. dt.Rows.Add("", , "手机");
  17. dt.Rows.Add("", , "服装");
  18.  
  19. var products = DataConvert<ProductEntity>.ToList(dt);
  20.  
  21. foreach (var entity in products)
  22. {
  23. Console.WriteLine(entity);
  24. }
  25.  
  26. Console.Read();
  27. }
  28. }
  29. }

示例代码下载:http://files.cnblogs.com/yjmyzz/DataConvertor.zip

C#:DataTable映射成Model的更多相关文章

  1. C# DataTable映射成Entity

    using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; ...

  2. DataTable转化为Model

    /// <summary> /// 将DataTable转成Model /// </summary> /// <param name="dt"> ...

  3. datatable转换为list<model> 映射

    using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.R ...

  4. DataTable转换成List<T>

    很多时候需要将DataTable转换成一组model,直接对model执行操作会更加方便直观. 代码如下: public static class DataTableToModel { public ...

  5. C# 中DataTable转成模型List

    C# 中DataTable转成模型List 引入using System.Reflection; 命名空间 使用注意实体类的属性名必须和DataTable的列名一致 使用: DBList<Sto ...

  6. DbUtility-关于DataTable转成List的效率问题

    DbUtility中的方法ExecuteDataTableAsync()得到的是一个DataTable,而我们常见的情况下,我们需要的不是DataTable,而是List或IList,所以现在需要考虑 ...

  7. C# DataTable转换成实体列表 与 实体列表转换成DataTable

    /// <summary> /// DataTable转换成实体列表 /// </summary> /// <typeparam name="T"&g ...

  8. C# 中 DataTable转换成IList

    在用C#作开发的时候经常要把DataTable转换成IList:操作DataTable比较麻烦,把DataTable转换成IList,以对象实体作为IList的元素,操作起来就非常方便. 注意:实体的 ...

  9. DataTable转换成IList

    //文章出处: http://www.cnblogs.com/hlxs/archive/2011/05/09/2087976.html DataTable转换成IList 在用C#作开发的时候经常要把 ...

随机推荐

  1. 1.9 基础知识——GP2.10 高级别的领导检查(Higher level management)

    GP2.10 Review the activities,status,and results of XXX process with highter level management and res ...

  2. NuGet学习笔记2——使用图形化界面打包自己的类库

    NuGet相对于我们最重要的功能是能够搭建自己的NuGet服务器,实现公司内部类库的轻松共享更新.在安装好NuGet扩展后,我们已经能够通过NuGet轻松下载自己需要的类库,下面来说一说如何将自己的项 ...

  3. 【转载】MySQL启多个实例

    很多朋友都想在一台服务器上运行多个MySQL Instance,究竟怎么做呢?首先要明晰几个原理, 简称为mysqld读取my.cnf的顺序:第一搜,首先读取/etc/my.cnf,多实例这个配置文件 ...

  4. 编写IoDemo.java的Java应用程序,程序完成的功能是:首先读取text.txt文件内容,再通过键盘输入文件的名称为iodemo.txt,把text.txt的内容存入iodemo.txt

    package zuoye; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundExcep ...

  5. C#正则表达式开源工具,为.net开源绵尽薄力

    先交代一下背景,最近工作中经常用到正则表达式,而正则表达式这个东西我个人觉得很鸡肋,不用吧,有些功能实现起来会很麻烦.用吧,又不是说工作中经常用到,只是有时候有些需要求用到而已.但是正则表达式只要一段 ...

  6. Oracle Data Provider for .NET

    官方地址: http://www.oracle.com/technetwork/topics/dotnet/index-085163.html 终于有正式版了.不用装客户端,又小,确实好.

  7. net-snmp添加自定义MIB

    我所知道的添加自定义MIB的方法有三种   1.静态加载,将生成的.c和.h文件加入到相应的位置,重新编译snmp库,优点是不需要修改配置文件,缺点是每次添加都得重新编译: 2.动态加载,将生成的.c ...

  8. ThinkPHP3.1.3源码分析---php文件压缩zlib.output_compression 和 ob_gzhandler

    问题来源:\ThinkPHP3.1.3_full\ThinkPHP\Lib\Core\App.class.php 中 init()方法      if(C('OUTPUT_ENCODE')){     ...

  9. PHP生成器Generators

    下文的第一个逐行读取文件例子用三种方式实现;普通方法,迭代器和生成器,比较了他们的优缺点,很好,可以引用到自己的代码中 ,支持的php版本(PHP 5 >= 5.5.0) 后面的yield讲解, ...

  10. python log

    python的日志模块为logging,它可以将我们想要的信息输出保存到一个日志文件中. # cat log import logging logging.debug('This is debug m ...