DataTable数据赋值给Model通用方法

王朝学院·作者佚名  2016-08-28
窄屏简体版  字體: 小  |  中  |  大  |  超大  

注:该文属本人原创,今后项目中发现该方法存在BUG会实时更新,转载记得附上原文出处,方便大家获得最新代码。

相信大家在做项目中,经常会根据不同的表new各种不同的Model,当需要对Model进行实例化的时候,先将数据从数据库取出,将该数据中的每个值都赋值给一个model,假如你有10个Model,每次都会从不同的表中获取数据,需要处理的数据完全不同,那么就要写10个方法,对着10个Model进行赋值。编码效率又低又low。为提高代码通用性,故写了个通用方法,实现datatable赋值model。

表结构(只是为了做演示,故没有对表中列属性进行相关设置,默认都允许为null):

CREATETABLE[AddressInfo]([Name][NVARCHAR](20)NULL,[Sex][NVARCHAR](2)NULL,[Address][NVARCHAR](50)NULL,[Age][INT]NULL,[Birthday][DATE]NULL)

Model类:

1publicclassAddressInfoModel2{34///<summary>5///姓名6///</summary>7publicstringName {get;set; }8///<summary>9///性别10///</summary>11publicstringSex {get;set; }12///<summary>13///地址14///</summary>15publicstringAddress {get;set; }16///<summary>17///年龄18///</summary>19publicint? Age {get;set; }20///<summary>21///生日22///</summary>23publicDateTime? Birthday {get;set; }2425}

通常我们得到Model实体是这样进行的:

1///<summary>2///得到一个对象实体3///</summary>4publicAddressInfo DataRowToModel(DataRow row)5{6Maticsoft.Model.addressinfo model=newMaticsoft.Model.addressinfo();7if(row !=null)8{9if(row["id"]!=null&& row["id"].ToString()!="")10{11model.id=int.Parse(row["id"].ToString());12}13if(row["name"]!=null)14{15model.name=row["name"].ToString();16}17if(row["Sex"]!=null)18{19model.Sex=row["Sex"].ToString();20}21if(row["Address"]!=null)22{23model.Address=row["Address"].ToString();24}25if(row["Age"]!=null&& row["Age"].ToString()!="")26{27model.Age=int.Parse(row["Age"].ToString());28}29if(row["Birthday"]!=null&& row["Birthday"].ToString()!="")30{31model.Birthday=DateTime.Parse(row["Birthday"].ToString());32}33}34returnmodel;35}36

相信这是大家常用的方法,该方法的好处是简单,容易理解,但是这样写会存在一个弊端,那就是方法通用性极差,甚至根本就没有通用性,而且日后也不易维护。

试想一下:

(1)如果我们有100个Model需要赋值,按照这样来做,我们岂不是需要写100个这样的方法来进行Model的赋值?

(2)一旦其中Model属性发生改变,那么对应的方法也必须发生相应的修改,如果客户不断提出改变要对Model属性进行修改,那工作量岂不是很大?

天哪!这工作量简直不敢想象。

通过对上面的思考,我们不难发现,不管有多少个Model其实在对其进行赋值时,所进行的逻辑处理都是有规律的重复性的工作,即将DataRow中的列赋值给对应Model属性。

经过一番努力终于通用方法第一个版本出炉(废话不多说直接上干货!)

(1)DataRow赋值Model通用方法之版本一:(该方法淘汰,仅为大家提供思路)

1///<summary>2///将DataRow中数据赋值给model中的同名属性3///</summary>4///<typeparam name="T">泛型:model的类型</typeparam>5///<param name="objmodel">model的实例</param>6///<param name="dtRow">DataRow</param>7publicT TableToModel<T>(T objmodel, DataRow dtRow)8{9//获取model的类型10Type modelType =typeof(T);11//获取model中的属性12PRopertyInfo[] modelpropertys =modelType.GetProperties();13//遍历DataTable的每一列14//遍历model的每一个属性15foreach(PropertyInfo piinmodelpropertys)16{17//获取属性名称18String name =pi.Name;19//将DataRow中数据赋值给model中的同名属性(不区分属性名称大小写name和Name效果一样)20if(dtRow.Table.Columns.Contains(name))21{22objectvalue =dtRow[name].ToString();23pi.SetValue(objmodel, value,null);24}25}26}

通过测试发现,该方法对于Model属性都是string类型的没有问题,该Model中Age为Int类型,Birthday为DateTime类型,会发生类型不能匹配的错误,故通用性极差。在此基础上出现了通用版本二

(2)DataRow赋值Model通用方法之版本二:(该方法淘汰,仅为大家提供思路)

将22行代码

22object 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通用方法之最终版:

1///<summary>2///将DataRow赋值给model中同名属性3///</summary>4///<typeparam name="T">泛型:model的类型</typeparam>5///<param name="objmodel">model实例</param>6///<param name="dtRow">DataTable行数据</param>7publicT TableRowToModel<T>(T objmodel, DataRow dtRow)8{9//获取model的类型10Type modelType =typeof(T);11//获取model中的属性12PropertyInfo[] modelpropertys =modelType.GetProperties();13//遍历model每一个属性并赋值DataRow对应的列14foreach(PropertyInfo piinmodelpropertys)15{16//获取属性名称17String name =pi.Name;18if(dtRow.Table.Columns.Contains(name))19{20//非泛型21if(!pi.PropertyType.IsGenericType)22{23pi.SetValue(objmodel,string.IsNullOrEmpty(dtRow[name].ToString()) ?null: Convert.ChangeType(dtRow[name], pi.PropertyType),null);24}25//泛型Nullable<>26else27{28Type genericTypeDefinition =pi.PropertyType.GetGenericTypeDefinition();29//model属性是可为null类型,进行赋null值30if(genericTypeDefinition ==typeof(Nullable<>))31{32//返回指定可以为 null 的类型的基础类型参数33pi.SetValue(objmodel,string.IsNullOrEmpty(dtRow[name].ToString()) ?null: Convert.ChangeType(dtRow[name], Nullable.GetUnderlyingType(pi.PropertyType)),null);34}35}36}37}38returnobjmodel;39}

最终实现DataRow数据赋值给Model

通过该方法便可简单实现将DataTable赋值给List<Model>!!(此处便不再给大家演示)

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航