阿不

不抛弃,不放弃

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  158 随笔 :: 0 文章 :: 2109 评论 :: 67 引用

在你的项目中,如果不使用ADO.NET对象,那么都要做一件事,就是要把查询的DataTable或IDataReader对象转换成实体对象,或者叫映射。比如ORM工具,它帮我们做好了所有事情,iBatis它帮我们完成了执行SQL和实体映射的工具。还有一些是使用Attribute + 反射的方式来实现。现在你又多了一种选择,你完全可以使用NBear.Mapping来帮你完成这个工作。这里的例子仍然使用上篇中定义的User类。

实体对象转DataRow

在有的情况下,你可能会希望把一个对象转换成DataRow,那么你这时可能会去定义与对象对应的DataTable的Schema,然后再用这个DataTable.NewRow()来创建一个DataRow对象,再将属性一个一个的进行赋值,会需要很多繁琐的步骤。这时候如果使用NBear.Mapping,情况会变成什么样呢?让我们来看看吧:

DataRow outputObject = ObjectConvertor.ToObject<DataRow>(user);

正如你所看到的,就一句代码就可以完成所有的工作。需要注意的是这时输出的DataRow仍是游离状态,并没有加到所属性的Table中。

DataRow转实体对象

反过来,如果你希望把一个DataRow对象转成实体对象的话,那么你可以使用类似的代码:

UserObject user = ObjectConvertor.ToObject<UserObject>(dataRow);

类似地,你也可以把IDataReader转成实体对象:

UserObject user = ObjectConvertor.ToObject<UserObject>(dataReader);

实体数组转成DataTable

把实体数组转成DataTable是一种最常见的需求了,使用NBear.Mapping这样就可以完成了:

DataTable dataTable = ObjectConvertor.ToDataTable(users, typeof(UserObject));

DataTable转成实体数组

反过来,把DataTable转成实体数据组呢?看下面代码吧:

List<UserObject> userList = ObjectConvertor.ToList<DataRow, UserObject>(dataTable);

那么把DataReader转成实体数组又该如何呢?

List<UserObject> userList = ObjectConvertor.ToList<IDataReader, UserObject>(dataTable);

正如你看到的,NBear.Mapping在处理这些工作的时候非常的游刃有余,而且确实是可以让你的工作更加轻松的。下篇你将会看到它是如何与其它弱类型(NameValueCollection,Dictionary)互转的。

示例代码下载

阿不

阿不 http://hjf1223.cnblogs.com
posted on 2007-12-18 19:26 阿不 阅读(2835) 评论(27)  编辑 收藏 所属分类: NBear

评论

#1楼  2007-12-18 20:00 stonezhu      
呵呵,挺快嘛,支持一个。
记得缓存哦:)
  回复  引用  查看    

#2楼  2007-12-18 21:59 flystudio [未注册用户]
我自己用的:
//dataset转实体类
public static IList<T> FillModel(DataSet ds)
{
List<T> l = new List<T>();
T model = default(T);

if (ds.Tables[0].Columns[0].ColumnName == "rowId")
{
ds.Tables[0].Columns.Remove("rowId");
}



foreach (DataRow dr in ds.Tables[0].Rows)
{


model = Activator.CreateInstance<T>();

foreach (DataColumn dc in dr.Table.Columns)
{

PropertyInfo pi = model.GetType().GetProperty(dc.ColumnName);
if (dr[dc.ColumnName] != DBNull.Value)
pi.SetValue(model, dr[dc.ColumnName], null);
else
pi.SetValue(model, null, null);

}
l.Add(model);
}

return l;


}

/// <summary>
/// 将实体类转换成DataTable
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="i_objlist"></param>
/// <returns></returns>
public static DataTable Fill<T>(IList<T> objlist)
{
if (objlist == null || objlist.Count <= 0)
{
return null;
}
DataTable dt = new DataTable(typeof(T).Name);
DataColumn column;
DataRow row;

System.Reflection.PropertyInfo[] myPropertyInfo = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

foreach (T t in objlist)
{
if (t == null)
{
continue;
}

row = dt.NewRow();

for (int i = 0, j = myPropertyInfo.Length; i < j; i++)
{
System.Reflection.PropertyInfo pi = myPropertyInfo[i];

string name = pi.Name;

if (dt.Columns[name] == null)
{
column = new DataColumn(name, pi.PropertyType);
dt.Columns.Add(column);
}

row[name] = pi.GetValue(t, null);
}

dt.Rows.Add(row);
}
return dt;
}


aspx@hotmail.com
  回复  引用    

#3楼  2007-12-18 23:08 macless [未注册用户]
确实不错.好东西.
  回复  引用    

#4楼  2007-12-19 08:17 MicEnter [未注册用户]
我顶。。。。。。
  回复  引用    

#5楼 [楼主] 2007-12-19 08:30 阿不      
@stonezhu
谢谢,缓存记得。我平常也注意缓存。
  回复  引用  查看    

#6楼 [楼主] 2007-12-19 08:32 阿不      
@flystudio [未注册用户]
NBear.Mapping的目的就是为了让用户能统计的进行这样的转换。并且提供最优的性能。NBear.Mapping不是使用反射,所以它的性能比较反射更优。
  回复  引用  查看    

#7楼  2007-12-20 15:02 阿桦 [未注册用户]
确实是好东西啊,顶个
  回复  引用    

可以作为范例了,呵呵
  回复  引用    

#9楼 [楼主] 2007-12-21 08:23 阿不      
@阿桦 [未注册用户],程序天堂 [未注册用户]
欢迎下载试用。
  回复  引用  查看    

#10楼  2007-12-24 11:31 len [未注册用户]
DataRow outputObject = ObjectConvertor.ToObject<DataRow>(user);

無法將資料行 'ID' 設定為 Null,請改用 DBNull。

这个要没有处理过吗
  回复  引用    

#11楼 [楼主] 2007-12-24 13:14 阿不      
@len
我在最新版本是没有出现这个异常呀?你是运行测试用例出错的吗?能不能下载最新版本再试试
  回复  引用  查看    

#12楼  2007-12-24 15:11 len [未注册用户]
NBearMapping V1.0.1.3 beta.rar
這個是最新版本的嗎?
  回复  引用    

#13楼  2007-12-24 15:20 len [未注册用户]
可以了,在你的官網上下載了一個就可以了,用用你的dll玩玩看
  回复  引用    

#14楼 [楼主] 2007-12-24 15:25 阿不      
@ len
:),欢迎使用。
  回复  引用  查看    

#15楼  2007-12-25 09:38 len [未注册用户]
DataTable dataTable = ObjectConvertor.ToDataTable(users, typeof(UserObject));

我这里该如何把datatable的数据更新到数据库呢
而且你这里的datarow的rowstate状态都为unchanged

请我这里该如何处理?
  回复  引用    

#16楼 [楼主] 2007-12-25 09:54 阿不      
@len
我在内部调用了dataTable.AcceptChanges();
你可以把这句注释了,我当初也考虑不要调用这句来改变状态。
我在以后的版本中会去掉这句的调用,由用户来决定是否DataTable的状态。
  回复  引用  查看    

#17楼  2007-12-25 10:32 len [未注册用户]
Microsoft.VisualStudio.TestTools.UnitTesting;
这个单元测试的类库哪里来啊?
与系统有关吗?

  回复  引用    

#18楼 [楼主] 2007-12-25 10:49 阿不      
@len
这是Vs2005的测试类库呀。
  回复  引用  查看    

#19楼  2007-12-25 10:59 len [未注册用户]
我知道是测试类库阿,我没有用过呢,他这个类库从哪里引用的阿
我看环境里面没有的,这个在开发中间件的时候用的比较多吧,我是从事页面程序开发的,所以平时对这个比较少使用
  回复  引用    

#20楼 [楼主] 2007-12-25 11:03 阿不      
@len
你能打打开测试工程吗?创建测试工程的时候就会自动引用这个程序集了。
  回复  引用  查看    

#21楼  2007-12-25 11:14 len [未注册用户]
能加我msn吗
lyq708@hotmail.com
  回复  引用    

#22楼 [楼主] 2007-12-25 11:24 阿不      
加了,不过不常上。
  回复  引用  查看    

#23楼 [楼主] 2007-12-25 11:24 阿不      
加了,不过不常上。
  回复  引用  查看    

#24楼  2007-12-25 17:01 WOW玩家      
能提供生成实体的工具吗?
  回复  引用  查看    

#25楼 [楼主] 2007-12-25 17:08 阿不      
@WOW玩家
什么实体生成工具啊?
  回复  引用  查看    

#26楼  2007-12-26 09:07 len [未注册用户]
codesmith,很好用
  回复  引用    

#27楼  2008-08-22 12:43 wangq [未注册用户]
很好,很强大
我充分用了NBear
  回复  引用    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-12-23 20:31 编辑过


相关链接: