c#中将datatable转成实体

8 篇文章 1 订阅

@[TOC] (c#中datatable转实体)

什么是databtable

	DataTable表示内存中数据的一个表,是一个后台数据源和前台显示之间的适配器。
	使用时需要引入命名空间
using System.Data;
DataTable table = new DataTable("Demo");
            table.Columns.Add("ID",typeof(int));//ID列
            table.Columns.Add("Name", typeof(string));//Name列
            table.Columns.Add("Age", typeof(int));//Age列
            table.Rows.Add(new object[] { 1, "李", 20 });//第一行(与列想对应)
            table.Rows.Add(new object[] { 2,"张",21});//第二行
            //获取表试图
            DataView dataView = table.DefaultView;
            //利用Sort属性,排序
            dataView.Sort = "ID DESC";//ID倒序
            dataView.ToTable();//创建为新的表格

以上就是创建了一个datatable实例,其实就是数据表结构。
在开发中我们需要根据实体进行数据的操作,操作数据库需要我们创建一个与表结构的列名相对应的实体。

public class Student()
{
public int ID{set;get;}
public string Name{get;set;}
public string Age{get;set;}
}

datatable与实体的相互转换

   int ID = (int)dt.Rows[0][0]; //这行是将datatable转成实体,datatable包含行和列,前一个0是第一行,后一个0表示第一列,
   //这里还可以使用数据库的列名来识别,int ID = (int)dt.Rows[0]["ID"]; 在实际开发中很多时候是循环赋值的。涉及到大数据时容易眼花,导致数据错误。
   string Name=dt.Rows[0][1].ToString();
   string Age=dt.Rows[0][2].ToString();

使用映射自动转实体

在面向大数据时,我们可以使用关系映射自动映射,能够避免错误,还能提高开发效率。这里涉及到反射的知识。

 public class TableHelpher
    {
        /// <summary>  
        /// 填充对象列表:用DataTable填充实体类
        /// </summary>  
        public static List<T> FillModels<T>(DataTable dt) where T: new() 
        {
        /*在C#中,泛型的使用非常广泛,为了泛型调用安全,经常需要对所使用的类型进行约束。

在对泛型的约束中,最常使用的关键字有where 和 new。

其中where关键字是约束所使用的泛型,该泛型必须是where后面的类,或者继承自该类。

new()说明所使用的泛型,必须具有无参构造函数,这是为了能够正确的初始化对象*/
            if (dt == null || dt.Rows.Count == 0)
            {
                return null;
            }
            List<T> modelList = new List<T>();
            var properties = typeof(T).GetProperties();//这里使用泛型,能够支持不同对象的映射取值
            foreach (DataRow dr in dt.Rows)
            {
                T model = (T)Activator.CreateInstance(typeof(T));
/*
使用与指定参数匹配程度最高的构造函数来创建指定类型的实例。

使用Activator.CreateInstance 的实际作用是什么呢?

是因为 想创建一个方法 方法中传入一个类的名称 然后就能返回一个这个类的实例 ,这样的做法让程序有更高的拓展性,
*/
                for (int i = 0; i < dr.Table.Columns.Count; i++)
                {
                    var propertyInfo = properties.FirstOrDefault(x => x.GetCustomAttribute<ModelFiledHelper>().DisplayName.Contains(dr.Table.Columns[i].ColumnName));
 /*propertyInfo变量接收转换的实体字段名
 FirstOrDefault:取序列中满足条件的第一个元素,如果没有元素满足条件,则返回默认值
 GetCustomAttribute:检索应用于类型的成员的自定义属性的数组。参数指定成员、要搜索的自定义属性的类型以及是否搜索成员的祖先。*/
                    if (propertyInfo != null && dr[i] != DBNull.Value)
                        try
                        {
                            propertyInfo.SetValue(model, dr[i], null);
                            /*为字段赋值*/
                        }
                        catch (Exception)
                        {
                        }
                }
                modelList.Add(model);
            }
            return modelList;
        }
        public static T FillModel<T>(DataRow dr)  where T : new () 
        {
            if (dr == null)
            {
                return default(T);
            }
            T model = new T();
            var properties = typeof(T).GetProperties();
            for (int i = 0; i < dr.Table.Columns.Count; i++)
            {
                var propertyInfo = properties.FirstOrDefault(x => x.GetCustomAttribute<ModelFiledHelper>().DisplayName.Contains(dr.Table.Columns[i].ColumnName));
           
                if (propertyInfo != null && dr[i] != DBNull.Value)
                    try
                    {
                        propertyInfo.SetValue(model, dr[i], null);
                    }
                    catch (Exception)
                    {
                    }
            }
            return model;
    }
//这里使用c#的特性
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Common.Common
{
    public class ModelFiledHelper : Attribute
    {
        public string[] DisplayName { get; private set; }
        public ModelFiledHelper(params string[] displayName)
        {
            DisplayName = displayName;
        }
        //使用构造函数初始化赋值。
    }
}
//在这里我们在实体中添加特性标识
public class Student()
{
 [ModelFiledHelper("ID")]
public int ID{set;get;}
 [ModelFiledHelper("Name")]
public string Name{get;set;}
 [ModelFiledHelper("Age")]
public string Age{get;set;}
}
 DataTable dt = new DataTable("Demo");//这里对应上边创建的datatable
 List<Student> viewList = new List<Student>();//这里声明数组接收多条数据
 if (dt != null && dt.Rows.Count > 0)
{
	var models = TableHelpher.FillModels<Student>(dt);
  models.ForEach(x => viewList.Add(x));
}

这种转换类型的方法能够在数据量多的时候不至于弄得混乱。但是相对于一些ORM框架来说,这种方法就显得微不足道了,但是大多数的ORM框架也都是采用反射这种方式的。总之只有在积累了非常多的知识才能明白大道至简的道理。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值