DataTable数据赋值给Model通用方法
注:该文属本人原创,今后项目中发现该方法存在BUG会实时更新,转载记得附上原文出处,方便大家获得最新代码。
相信大家在做项目中,经常会根据不同的表new各种不同的Model,当需要对Model进行实例化的时候,先将数据从数据库取出,将该数据中的每个值都赋值给一个model,假如你有10个Model,每次都会从不同的表中获取数据,需要处理的数据完全不同,那么就要写10个方法,对着10个Model进行赋值。编码效率又低又low。为提高代码通用性,故写了个通用方法,实现datatable赋值model。
表结构(只是为了做演示,故没有对表中列属性进行相关设置,默认都允许为null):
CREATE TABLE [AddressInfo](
[Name] [NVARCHAR](20) NULL,
[Sex] [NVARCHAR](2) NULL,
[Address] [NVARCHAR](50) NULL,
[Age] [INT] NULL,
[Birthday] [DATE] NULL
)
Model类:
public class AddressInfoModel
{ /// <summary>
/// 姓名
/// </summary>
public string Name { get; set; }
/// <summary>
/// 性别
/// </summary>
public string Sex { get; set; }
/// <summary>
/// 地址
/// </summary>
public string Address { get; set; }
/// <summary>
/// 年龄
/// </summary>
public int? Age { get; set; }
/// <summary>
/// 生日
/// </summary>
public DateTime? Birthday { get; set; } }
通常我们得到Model实体是这样进行的:
/// <summary>
/// 得到一个对象实体
/// </summary>
public AddressInfo DataRowToModel(DataRow row)
{
Maticsoft.Model.addressinfo model=new Maticsoft.Model.addressinfo();
if (row != null)
{
if(row["id"]!=null && row["id"].ToString()!="")
{
model.id=int.Parse(row["id"].ToString());
}
if(row["name"]!=null)
{
model.name=row["name"].ToString();
}
if(row["Sex"]!=null)
{
model.Sex=row["Sex"].ToString();
}
if(row["Address"]!=null)
{
model.Address=row["Address"].ToString();
}
if(row["Age"]!=null && row["Age"].ToString()!="")
{
model.Age=int.Parse(row["Age"].ToString());
}
if(row["Birthday"]!=null && row["Birthday"].ToString()!="")
{
model.Birthday=DateTime.Parse(row["Birthday"].ToString());
}
}
return model;
}
相信这是大家常用的方法,该方法的好处是简单,容易理解,但是这样写会存在一个弊端,那就是方法通用性极差,甚至根本就没有通用性,而且日后也不易维护。
试想一下:
(1)如果我们有100个Model需要赋值,按照这样来做,我们岂不是需要写100个这样的方法来进行Model的赋值?
(2)一旦其中Model属性发生改变,那么对应的方法也必须发生相应的修改,如果客户不断提出改变要对Model属性进行修改,那工作量岂不是很大?
天哪!这工作量简直不敢想象。
通过对上面的思考,我们不难发现,不管有多少个Model其实在对其进行赋值时,所进行的逻辑处理都是有规律的重复性的工作,即将DataRow中的列赋值给对应Model属性。
经过一番努力终于通用方法第一个版本出炉(废话不多说直接上干货!)
(1)DataRow赋值Model通用方法之版本一:(该方法淘汰,仅为大家提供思路)
/// <summary>
/// 将DataRow中数据赋值给model中的同名属性
/// </summary>
/// <typeparam name="T">泛型:model的类型</typeparam>
/// <param name="objmodel">model的实例</param>
/// <param name="dtRow">DataRow</param>
public T TableToModel<T>(T objmodel, DataRow dtRow)
{
//获取model的类型
Type modelType = typeof(T);
//获取model中的属性
PropertyInfo[] modelpropertys = modelType.GetProperties();
//遍历DataTable的每一列
//遍历model的每一个属性
foreach (PropertyInfo pi in modelpropertys)
{
//获取属性名称
String name = pi.Name;
//将DataRow中数据赋值给model中的同名属性(不区分属性名称大小写name和Name效果一样)
if (dtRow.Table.Columns.Contains(name))
{
object value = dtRow[name].ToString();
pi.SetValue(objmodel, value, null);
}
}
}
通过测试发现,该方法对于Model属性都是string类型的没有问题,该Model中Age为Int类型,Birthday为DateTime类型,会发生类型不能匹配的错误,故通用性极差。在此基础上出现了通用版本二
(2)DataRow赋值Model通用方法之版本二:(该方法淘汰,仅为大家提供思路)
将22行代码
22 object value = dtRow[name].ToString();
修改为
object value = Convert.ChangeType(dtRow[name], modelType.GetProperty(name).PropertyType);
解决DataRow类型与Model类型不匹配问题 此时,该方法已经很好的通用性,着实高兴了一下,但是当测试中,数据库中自读允许为null的情况下,该方法便不能适应复杂多变的Model赋值。例如该类中年龄和出生年月字段是允许为空的
即 int? Age 和DateTime? Birthday会报错,不能将null值赋值给指定的数据类型,因为进一步改进该方法,最终版本如下:
(3)DataRow赋值Model通用方法之最终版:
/// <summary>
/// 将DataRow赋值给model中同名属性
/// </summary>
/// <typeparam name="T">泛型:model的类型</typeparam>
/// <param name="objmodel">model实例</param>
/// <param name="dtRow">DataTable行数据</param>
public T TableRowToModel<T>(T objmodel, DataRow dtRow)
{
//获取model的类型
Type modelType = typeof(T);
//获取model中的属性
PropertyInfo[] modelpropertys = modelType.GetProperties();
//遍历model每一个属性并赋值DataRow对应的列
foreach (PropertyInfo pi in modelpropertys)
{
//获取属性名称
String name = pi.Name;
if (dtRow.Table.Columns.Contains(name))
{
//非泛型
if (!pi.PropertyType.IsGenericType)
{
pi.SetValue(objmodel, string.IsNullOrEmpty(dtRow[name].ToString()) ? null : Convert.ChangeType(dtRow[name], pi.PropertyType), null);
}
//泛型Nullable<>
else
{
Type genericTypeDefinition = pi.PropertyType.GetGenericTypeDefinition();
//model属性是可为null类型,进行赋null值
if (genericTypeDefinition == typeof(Nullable<>))
{
//返回指定可以为 null 的类型的基础类型参数
pi.SetValue(objmodel, string.IsNullOrEmpty(dtRow[name].ToString()) ? null : Convert.ChangeType(dtRow[name], Nullable.GetUnderlyingType(pi.PropertyType)), null);
}
}
}
}
return objmodel;
}
最终实现DataRow数据赋值给Model 通过该方法便可简单实现将DataTable赋值给List<Model>!!(此处便不再给大家演示)
DataTable数据赋值给Model通用方法的更多相关文章
- 怎样简单灵活地将DataTable中的数据赋值给model
最近在做的一个项目中,有13个方法都需要用到同一种处理方式:通过SQL语句从数据库获取一条指定的数据,并将该数据中的每个值都赋值给一个model,再将这个model中的数据通过微信发送出去.每个方法都 ...
- DataTable中的数据赋值给model z
create table memberinfo ( member_id int, member_name varchar(20), member_birthday varchar(50) ) go / ...
- 利用反射把DataTable自动赋值到Model实体(自动识别数据类型)
转:http://www.cnblogs.com/the7stroke/archive/2012/04/22/2465591.html using System.Collections.Generic ...
- js获取或判断任意数据类类型的通用方法(getDataType)和将NodeList转为数组(NodeListToArray)
function getDataType(any){ /* (1) Object.prototype.toString.call 方法判断类型: 优点:通用,返回"[object Strin ...
- golang获取数据表转换为json通用方法
package main import ( "database/sql" "fmt" "log" "net/http" ...
- C#将DataTable数据导出CSV文件
C#将DataTable数据导出CSV文件通用方法! //导出按钮调用导出方法 protected void btnCSV_Click(object sender, EventArgs e) ...
- 筛选DataTable数据的方法
对DataTable进行过滤筛选的一些方法Select,dataview 当你从数据库里取出一些数据,然后要对数据进行整合,你很容易就会想到: DataTable dt = new DataTable ...
- DataTable转List<Model>通用类【实体转换辅助类】
/// <summary> /// DataTable转List<Model>通用类[实体转换辅助类] /// </summary> public class Mo ...
- 批量插入数据, 将DataTable里的数据批量写入数据库的方法
大量数据导入操作, 也就是直接将DataTable里的内容写入到数据库 通用方法: 拼接Insert语句, 好土鳖 1. MS Sql Server: 使用SqlBulkCopy 2. MySql ...
随机推荐
- GitHub使用心得
PHP今天算是学习结束了;版本控制也了解很久了,比较熟悉的是svn,Git一直都不太熟,也可能是它是英文的缘故,感觉很费劲,所以用的不多,但不得不说,它功能真的很强大;今天试着和朋友用Git开发一个简 ...
- Linux的tmpfs文件系统
转载:http://blog.csdn.net/wxwsixis/article/details/5752186 前几天发现服务器的内存(ram)和swap使用率非常低,于是就想这么多的资源,不用岂不 ...
- 一个N*M的矩阵,找出这个矩阵中所有元素的和不小于K的面积最小的子矩阵
题目描述: 一个N*M的矩阵,找出这个矩阵中所有元素的和不小于K的面积最小的子矩阵(矩阵中元素个数为矩阵面积) 输入: 每个案例第一行三个正整数N,M<=100,表示矩阵大小,和一个整数K 接下 ...
- OpenCV成长之路(2):图像的遍历
我们在实际应用中对图像进行的操作,往往并不是将图像作为一个整体进行操作,而是对图像中的所有点或特殊点进行运算,所以遍历图像就显得很重要,如何高效的遍历图像是一个很值得探讨的问题. 一.遍历图像的4种方 ...
- 转--脉络清晰的BP神经网络讲解,赞
http://www.cnblogs.com/wengzilin/archive/2013/04/24/3041019.html 学 习是神经网络一种最重要也最令人注目的特点.在神经网络的发展进程中, ...
- HDU 1712 ACboy needs your help(分组背包)
题意:给你n的课程组,每个课程组有m个课程,每个课程有一个完成时间与价值.问在m天内每组课程组最多选择一个,这样可以得到的最大价值是多少 题解:分组背包,其实就是每个课程组进行01背包,再在课程组内部 ...
- HDU 2082 找单词 (多重背包)
题意:假设有x1个字母A, x2个字母B,..... x26个字母Z,同时假设字母A的价值为1,字母B的价值为2,..... 字母Z的价值为26.那么,对于给定的字母,可以找到多少价值<=50的 ...
- Hello world!(OC)
#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { NSLog(@"Hello ...
- offset图
- [LeetCode] Single Number
Given an array of integers, every element appears twice except for one. Find that single one. Note: ...