在项目开发过程中,需要我们将数据库表中的数据读出来,转换为实体类方便操作,因为我们总不想对每一个DataTable进行操作,用DataReader读取数据然后对实体对象赋值虽简单但是如果字段多了的话也很麻烦。
有如下用户的实体类:
public class User { private int _userid; private string _username; private string _passerword; private string _sex; /// <summary> /// 用户表主键 /// </summary> public int userID { set { _userid = value; } get { return _userid; } } /// <summary> /// 用户名 /// </summary> public string userName { set { _username = value; } get { return _username; } } /// <summary> /// 密码 /// </summary> public string passerWord { set { _passerword = value; } get { return _passerword; } } /// <summary> /// 性别 0男,1女,2保密 /// </summary> public string sex { set { _sex = value; } get { return _sex; } } }
数据库中数据表有如上相同字段。如果我们用DataReader读取出数据对其赋值的话往往是这样
List<User> mUserList = new List<User>(); SqlConnection mConn = new SqlConnection(); SqlCommand mCommand = new SqlCommand("Select * form User", mConn); SqlDataReader sda = mCommand.ExecuteReader(); if (sda != null) { while (sda.Read()) { User mUser = new User(); mUser.userID = (int)sda["UserID"]; mUser.userName = sda["userName"].ToString(); mUserList.Add(mUser); } } sda.Close(); mConn.Close();
通过以上代码我们就能够获取一个List.但是如果字段很多的话就不太实用,可用反射的方法很方便的实现赋值的过程,如下方法:
/// <summary> /// 用反射将DataReader对象转换为实体 /// </summary> /// <param name="reader">IDataReader对象</param> /// <param name="targetObj">转换成的实体</param> public static void ReaderToObject(IDataReader reader, object targetObj) { try { for (int i = 0; i < reader.FieldCount; i++) { System.Reflection.PropertyInfo propertyInfo = targetObj.GetType().GetProperty(reader.GetName(i)); if (propertyInfo != null) { if (reader.GetValue(i) != DBNull.Value) { if (propertyInfo.PropertyType.IsEnum) { propertyInfo.SetValue(targetObj, Enum.ToObject(propertyInfo.PropertyType, reader.GetValue(i)), null); } else { propertyInfo.SetValue(targetObj, reader.GetValue(i), null); } } } } } catch { throw; } }
只需传入Reader对象与实体类对象即可完成赋值 则之前User的List对象的读取可变成
while (sda.Read()) { User mUser = new User(); ReaderToObject(sda, mUser);//调用反射方法 装换为实体类 mUserList.Add(mUser); }
同样我们也会遇到为存储过程批量添加参数的情况 如下如果我们想将一个User对象插入数据表中 则需要 SqlConnection mConn = new SqlConnection(); SqlCommand mCommand = new SqlCommand(); mCommand.Parameters.Clear(); mCommand.Parameters.Add("userName", aUser.userName); mCommand.Parameters.Add("sex", aUser.sex);
用Add方法对对象的没个属性进行插入也可用如下方法来减小工作量 /// <summary> /// 为SqlCommand添加参数 /// </summary> /// <param name="aEntityObj">实体对象</param> /// <param name="aSqlCommand">SqlCommand对象</param> public static void AddqEntityParameters(object aEntityObj, SqlCommand aSqlCommand) { try { if (aEntityObj != null) { PropertyInfo[] propertyInfo = aEntityObj.GetType().GetProperties();//获取对象的所有共有属性 if (propertyInfo != null) { foreach (PropertyInfo aPro in propertyInfo)//遍历每个属性 { string propertyInfoName = aPro.Name;//获取属性的名 object propertyInfoValue = aPro.GetValue(aEntityObj, null);//获取对象该属性的值 if (propertyInfoValue != null) { aSqlCommand.Parameters.AddWithValue(propertyInfoName, propertyInfoValue);//添加到参数 } } } } } catch { throw; } } }
在使用以上两个方法的时候,数据库查询出来的字段以及数据库参数的名称,实体类属性要相同,第二个方法中,如果是DataTime类型,int类型的话可能会产生异常。编码现在,规划未来。