阿不

不抛弃,不放弃

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

不断有朋友希望能提供一些示例,同时我也发现,单纯发一些文字性的教程。大家好像都没有看明白NBear.Mapping是干嘛用的,所以从这篇开始我会陆续以实例的方式介绍NBear.Mapping的使用,以便给大家直观的印象。这篇我们首先关注的是对象与对象间映射,在这篇文章里你将会看到。即使你的项目不需要与数据库的映射,NBear.Mapping在日常开发中也会给你带来非常大的帮助。

就如之前教程介绍的那样,有一个IUser接口,这个接口定义了用户的一些基本属性:

   1: public enum UserStatus
   2: {
   3:     Normal,
   4:     Admin
   5: }
   6: public interface IUser
   7: {
   8:     int? ID { get;set;}
   9:     string Name { get;set;}
  10:     string Address { get;set;}
  11:     int Age { get;set;}
  12:     UserStatus Status { get;set;}
  13: }

我们用一个类UserObject来实现它,这个类型除了实现IUser接口外,还有一个自定义的属性Password:

   1: public class UserObject : IUser
   2:     {
   3:         #region IUser Members
   4:         private string name;
   5:         public string Name
   6:         {
   7:             get
   8:             {
   9:                 return name;
  10:             }
  11:             set
  12:             {
  13:                 name = value;
  14:             }
  15:         }
  16:  
  17:         private int? id;
  18:         public int? ID
  19:         {
  20:             get
  21:             {
  22:                 return id;
  23:             }
  24:             set
  25:             {
  26:                 id = value;
  27:             }
  28:         }
  29:         string address;
  30:         public string Address
  31:         {
  32:             get
  33:             {
  34:                 return address;
  35:             }
  36:             set
  37:             {
  38:                 address = value;
  39:             }
  40:         }
  41:         int age;
  42:         public int Age
  43:         {
  44:             get
  45:             {
  46:                 return age;
  47:             }
  48:             set
  49:             {
  50:                 age = value;
  51:             }
  52:         }
  53:  
  54:         UserStatus status;
  55:         public UserStatus Status
  56:         {
  57:             get
  58:             {
  59:                 return status;
  60:             }
  61:             set
  62:             {
  63:                 status = value;
  64:             }
  65:         }
  66:  
  67:         #endregion
  68:  
  69:         private string password;
  70:  
  71:         public string Password
  72:         {
  73:             get { return password; }
  74:             set { password = value; }
  75:         }
  76:  
  77:         public UserObject() { }
  78:  
  79:         public UserObject(int? id, string name, string address, int age, UserStatus status, string password)
  80:         {
  81:             this.id = id;
  82:             this.name = name;
  83:             this.address = address;
  84:             this.age = age;
  85:             this.status = status;
  86:             this.password = password;
  87:         }
  88:     }

这时,我们希望将一个UserObject实例的属性拷贝到另一个UserObject实例中,那么我们可能会使用如下的代码:

   1: UserObject user = new UserObject(1, "abu", "fuzhou", 24, UserStatus.Admin,"*&3345-+¥");
   2: UserObject userObject = new UserObject();
   3: userObject.Address = user.Address;
   4: userObject.Age = user.Age;
   5: userObject.ID = user.ID;
   6: userObject.Name = user.Name;
   7: userObject.Password = user.Password;
   8: userObject.Status = user.Status;

当然,如果单纯的都是这样的属性拷贝的话,那完全可以通过实现ICloneable接口,来实现对象的浅拷贝。但是如果我们使用NBear.Mapping的话,那我们的代码将会变成这样:

   1: UserObject user = new UserObject(1, "abu", "fuzhou", 24, UserStatus.Admin,"*&3345-+¥");
   2: UserObject outputObject = ObjectConvertor.ToObject<UserObject>(user);

你会发现你的对象转换代码将会变的非常干净简单。此时,在保证系统安全的情况下,我并不希望Password字段参与拷贝工作,那么我们有几下几种做法:

1、修改代码,使用ObjectConvertor.ToObject<InputType,OutputType>(user)的形式,如下:

   1: UserObject outputObject = ObjectConvertor.ToObject<IUser,UserObject>(user);

这时,参与对象拷贝的就只有IUser接口里所定义的属性字段了。

2、不改变原有代码,在配置文件中增加这样的一段配置,就可以让过滤掉Password的拷贝:

   1: <object inputType="UserObject" outputType="UserObject">
   2:   <views>
   3:     <view name="Default">
   4:       <ignoreProperties>
   5:         <add destName="Password"></add>
   6:       </ignoreProperties>
   7:     </view>
   8:   </views>
   9: </object>
  10: <mappings>

以上是两种最简单的做法,通过NBear.Mapping,还有其它的调用方法来达到这个目的。

这篇博客比较短,目的是希望能让大家对NBear.Mapping有直观的印象。示例代码下载

阿不

阿不 http://hjf1223.cnblogs.com
posted on 2007-12-17 20:08 阿不 阅读(3050) 评论(14)  编辑 收藏 所属分类: NBear

评论

#1楼  2007-12-17 20:27 技术菜鸟      
不错,学习中...
  回复  引用  查看    

#2楼  2007-12-17 21:53 stonezhu      
支持一下,稍后研究
  回复  引用  查看    

#3楼  2007-12-17 21:53 笑疯^_^      
继续关注中....
  回复  引用  查看    

#4楼  2007-12-18 08:28 浪子      
Q1:是否支持各种类型的属性?

比如最近碰到的一个例子,是MailMessage的拷贝。

需要从一个MailMessage实例拷贝到另外一个MailMessage实例,其中有很多集合,比如CC的MailAddressCollection,Attachments的MailAttachments。


Q2:如果我是完全映射,是否不需要做任何配置文件的设置?

  回复  引用  查看    

#5楼 [楼主] 2007-12-18 08:39 阿不      
@浪子
Answer Q1:对象的映射目前只能实现对一级属性的映射,也就是说对一级的值类型的映射(包括string),并不能实现对对象是引用类型的嵌套映射,如果你希望能嵌套映射可以自己实现一个ICustomObjectMemberMapping类型,在配置文件里指定就行了。

Answer Q2:如果是完全映射,你不需要指定任何配置即可。
  回复  引用  查看    

#6楼  2007-12-18 09:06 召冠      
@阿不
==================================================
"对象的映射目前只能实现对一级属性的映射,也就是说对一级的值类型的映射(包括string),并不能实现对对象是引用类型的嵌套映射"
==================================================

其实 ObjectConvertor.ToObject<Type>(obj) 方法就是利用元数据操作对象(PropertyInfo 的 getValue、 setValue方法)。
如果要实现对象的引用类型属性的复制,只要把ToObject方法写成递归的应该就可以了。

  回复  引用  查看    

#7楼 [楼主] 2007-12-18 09:09 阿不      
@召冠
是这样的,呵呵。
  回复  引用  查看    

#8楼  2007-12-18 09:20 浪子      
原来如此。

--引用--------------------------------------------------
阿不: @浪子
Answer Q1:对象的映射目前只能实现对一级属性的映射,也就是说对一级的值类型的映射(包括string),并不能实现对对象是引用类型的嵌套映射,如果你希望能嵌套映射可以自己实现一个ICustomObjectMemberMapping类型,在配置文件里指定就行了。

Answer Q2:如果是完全映射,你不需要指定任何配置即可。
--------------------------------------------------------

  回复  引用  查看    

#9楼 [楼主] 2007-12-18 09:23 阿不      
@ 浪子
因为对引用类型属性的映射,没有办法做,如果它是一个接口,或没有构造器的类型时,无法去映射了。
  回复  引用  查看    

在使用NBearLite时,调用SqlTransaction做事务查询可能会导致数据库死锁。
若使用TransactionScope则似乎没有问题。
不知道是不是我的使用不恰当,还是NBearLite存在Bug?
  回复  引用    

#11楼 [楼主] 2007-12-18 09:51 阿不      
@volcanodeng [未注册用户]
你使用的是什么样的代码?能给我发个邮件吗?
hjf1223(at)gmail.com
  回复  引用  查看    

#12楼  2007-12-18 16:28 stonezhu      
貌似用起来挺简单,想问一下,NB4有没有对缓存这块做比较好的处理?
  回复  引用  查看    

#13楼 [楼主] 2007-12-18 16:49 阿不      
@stonezhu
使用是很简单的。NB4中,对缓存这块目前还没有成型,我再与teddy商量一下,看能不能把成熟的缓存实现,比如微软的企业库的核心功能移植过来,包括它的定期过期释放机制。
  回复  引用  查看    

#14楼  2007-12-18 19:58 stonezhu      
@阿不
恩,这样比较好啊,缓存还是非常重要的东西

  回复  引用  查看    


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


相关链接:

历史上的今天:
2005-12-17 IBatisNet 1.3 Beta Release