C#实现DataTable映射成Model的方法(附源码)

所属分类: 软件编程 / C#教程 阅读数: 62
收藏 0 赞 0 分享

本文实例讲述了C#实现DataTable映射成Model的方法。分享给大家供大家参考,具体如下:

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

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

步骤1:先创建一个DataFieldAttribute类

using System;
namespace Jimmy.ORM
{
 [AttributeUsage(AttributeTargets.Property)]
 public sealed class DataFieldAttribute:Attribute
 {
 /// <summary>
 /// 表对应的字段名
 /// </summary>
 public string ColumnName { set; get; }
 public DataFieldAttribute(string columnName)
 {
  ColumnName = columnName;
 }
 }
}

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

using System;
namespace Jimmy.ORM.Entity
{
 [Serializable]
 public class ProductEntity : DataEntityBase
 {
 [DataField("PRODUCT_NO")]
 public string ProductNo { set; get; }
 [DataField("PRODUCT_ID")]
 public int ProductId { set; get; }
 [DataField("PRODUCT_NAME")]
 public string ProductName { set; get; }
 public override string ToString()
 {
  return string.Format("ProductNo:{1}{0}ProductId:{2}{0}ProductName:{3}", Environment.NewLine, ProductNo,
     ProductId, ProductName);
 }
 }
}

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

using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
namespace Jimmy.ORM
{
 /// <summary>
 /// 将DataRow/DataTable转换成Entity/Entity列表
 /// </summary>
 public static class DataConvert<T> where T : DataEntityBase, new()
 {
 /// <summary>
 /// 将DataRow行转换成Entity
 /// </summary>
 /// <param name="dr"></param>
 /// <returns></returns>
 public static T ToEntity(DataRow dr)
 {
  T entity = new T();
  Type info = typeof(T);
  var members = info.GetMembers();
  foreach (var mi in members)
  {
  if (mi.MemberType == MemberTypes.Property)
  {
   //读取属性上的DataField特性
   object[] attributes = mi.GetCustomAttributes(typeof(DataFieldAttribute), true);
   foreach (var attr in attributes)
   {
   var dataFieldAttr = attr as DataFieldAttribute;
   if (dataFieldAttr != null)
   {
    var propInfo = info.GetProperty(mi.Name);
    if (dr.Table.Columns.Contains(dataFieldAttr.ColumnName))
    {
    //根据ColumnName,将dr中的相对字段赋值给Entity属性
    propInfo.SetValue(entity,
     Convert.ChangeType(dr[dataFieldAttr.ColumnName], propInfo.PropertyType),
     null);
    }
   }
   }
  }
  }
  return entity;
 }
 /// <summary>
 /// 将DataTable转换成Entity列表
 /// </summary>
 /// <param name="dt"></param>
 /// <returns></returns>
 public static List<T> ToList(DataTable dt)
 {
  List<T> list = new List<T>(dt.Rows.Count);
  foreach (DataRow dr in dt.Rows)
  {
  list.Add(ToEntity(dr));
  }
  return list;
 }
 }
}

步骤4:测试

using System;
using System.Data;
using Jimmy.ORM.Entity;
namespace Jimmy.ORM.Test
{
 class Program
 {
 static void Main()
 {
  DataTable dt = new DataTable();
  dt.Columns.Add("PRODUCT_NO");
  dt.Columns.Add("PRODUCT_ID");
  dt.Columns.Add("PRODUCT_NAME");
  dt.Rows.Add("00001", 1, "手机");
  dt.Rows.Add("00002", 2, "服装");
  var products = DataConvert<ProductEntity>.ToList(dt);
  foreach (var entity in products)
  {
  Console.WriteLine(entity);
  }
  Console.Read();
 }
 }
}

完整实例代码代码点击此处本站下载

希望本文所述对大家C#程序设计有所帮助。

更多精彩内容其他人还在看

C# SendInput 模拟鼠标操作的实现方法

C# SendInput 模拟鼠标操作的实现方法,需要的朋友可以参考一下
收藏 0 赞 0 分享

C#中 paint()与Onpaint()的区别

paint是事件onpaint方法onpaint方法是调用paint事件的,用哪一个,效果是一样,就看那一个方便了内部是这样实现的:
收藏 0 赞 0 分享

c#中GetType()与Typeof()的区别

c#中GetType()与Typeof()的区别,需要的朋友可以参考一下
收藏 0 赞 0 分享

将字符串转换成System.Drawing.Color类型的方法

将字符串转换成System.Drawing.Color类型的方法,需要的朋友可以参考一下
收藏 0 赞 0 分享

C# 抓取网页内容的方法

C# 抓取网页内容的方法,需要的朋友可以参考一下
收藏 0 赞 0 分享

基于C#后台调用跨域MVC服务及带Cookie验证的实现

本篇文章介绍了,基于C#后台调用跨域MVC服务及带Cookie验证的实现。需要的朋友参考下
收藏 0 赞 0 分享

使用C#获取远程图片 Form用户名与密码Authorization认证的实现

本篇文章介绍了,使用C#获取远程图片 Form用户名与密码Authorization认证的实现。需要的朋友参考下
收藏 0 赞 0 分享

Winform跨线程操作的简单方法

线程间操作无效:从不是创建控件“label1”的线程访问它
收藏 0 赞 0 分享

C# WINFORM 强制让窗体获得焦点的方法代码

C# WINFORM 强制让窗体获得焦点的方法代码,需要的朋友可以参考一下
收藏 0 赞 0 分享

C#中方括号[]的语法及作用介绍

C#中方括号[]可用于数组,索引、属性,更重要的是用于外部DLL类库的引用。
收藏 0 赞 0 分享
查看更多