Fluent NHibernate之旅二--Entity Mapping

简单实体映射

  使用自定义类型映射实体属性

  NHibernate的实体映射(Entity Mapping)做的非常好,虽然不是完美,但一些我们经常使用的,基本上已经都支持了,而且配置也相对比较简单。好了,开始我们的体验之旅吧。

  一、简单实体映射

  为了配合今后的教程,我们以一个简单的电子商务平台说起。一个B2C的电子商务,我们一定需要产品和订单,因为是示例,所以尽可能的简单,我们先设计两张表:Order 和 Product


我们先写Entity Model,无论传统方式还是Fluent,都需要这个Model。


public class Product 
{ 
  public virtual int ProductID { get; set; } 
 
  public virtual string Name { get; set; } 
 
  public virtual decimal Price { get; set; } 
 
  public virtual DateTime CreateTime { get; set; } 
} 
 
public class Order 
{ 
  public virtual int OrderID { get; set; } 
 
  public virtual decimal Price { get; set; } 
 
  public virtual OrderState State { get; set; } 
 
  public virtual DateTime CreateTime { get; set; } 
} 
 
public enum OrderState 
{ 
  Created, 
  Paied, 
  Consignment, 
  Complete, 
}

稍微简单介绍下,订单有订单号、总价、订单状态、创建时间等属性,状态现在是int类型,过后我演示一下如何使用枚举型。产品有产品ID,产品名,价格,创建时间。今天的内容不涉及关联关系,所以我们今天暂且不说Order。

  好了,接下来开始我们的代码演示阶段。

  传统方式:传统方式使用xml文件进行映射,配置文件如下:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="EntityModel" assembly="EntityModel"> 
 <class name="Product" table="Product"> 
  <id name="ProductID"> 
   <generator class="native" /> 
  </id> 
  <property name="Name"> 
   <column name="Name" length="50" sql-type="varchar(50)" not-null="true" /> 
  </property> 
  <property name="Price"> 
   <column name="Price" sql-type="real" not-null="true" /> 
  </property> 
  <property name="CreateTime"> 
   <column name="CreateTime" sql-type="datetime" not-null="true" /> 
  </property> 
 </class> 
</hibernate-mapping>

Order的映射大体与Product相似。

  Fluent方式:或许你会觉得我们用了配置文件进行映射,相当的简单,想怎么配就可以了,但实际用下来,我还是更喜欢Fluent的映射方式,映射代码如下:

public class ProductMap : ClassMap<Product> 
{ 
  public ProductMap() 
  { 
    Id(m => m.ProductID); 
    Map(m => m.Name); 
    Map(m => m.Price).ColumnName("Price"); 
    Map(m => m.CreateTime); 
  } 
}

我们只需要继承Fluent的ClassMap<T>类,然后在构造方法中完成映射方法,就能完成传统方式的映射了。映射的方式很简单吧,相信大家都能看懂吧,为什么会如此方便呢?这其实就是完全靠了Lambda表达式,大家可以看看老赵的“从.NET框架中委托写法的演变谈开去”,就非常清楚了。我们来看看Id和Map

  Id(Expression<Func<T, object>> expression):一看就很明白了,主键嘛,因为有了VS,因为有了泛型,因为有了委托,因为……,我们只需要简单的 m => m.ProductID,可能你会说主键的类型,主键还有很多特性,难道不需要配置吗?回答是当然需要,因为我们这里的属性名与表中的主键名是相同的,所以没有进行设置,如果你数据库的主键名是ID,这里我们只需要Id(m => m.ProductID).ColumnName(“ID”),你可以看到上述映射中的Price,我用了一下,其实不用也是没有关系的,只是做演示。当然还有很多,因为有了智能感知,我们只要.一下就能看到很多方法,但有一点你要注意,.ColumnName()后就不能再进行配置了,所以其他一些配置,你要放在ColumName之前。



 Map(Expression<Func<T, object>> expression):与Id类似,对应NHibernate中的property,我这里只是简单的映射,还有很多特性,在今后的教程中会慢慢使用。

  两者之间的对比,只有用了以后你才能懂得,只能意传不能言语。对于我这种新手来说,Fluent更适合我,因为我可以用它来进行学习NHibernate。

  映射做好了,接下来我们在NHibernate中把映射加到配置中。

  传统方式:



<mapping assembly="MyNHibernate"/> 


  Fluent:
private static ISessionFactory CreateSessionFactory() 
{ 
  return Fluently.Configure() 
    .Database(MsSqlConfiguration.MsSql2005 
      .ConnectionString(s => s.Server(".") 
        .Database("MyNHibernate") 
        .TrustedConnection())) 
    .Mappings(m => m.FluentMappings.AddFromAssembly(typeof(FluentSessionFactory).Assembly).ExportTo("c:\path")) 
    .BuildSessionFactory(); 
}

Fluent的方式比上一篇中多了Mappings方法,Mappings的配置方式有很多,我这里用了最简单的FluentMappings.AddFromAssembly,只要添加Entity Mapping所在的程序集就可以了。当然还有更多的方法,如果大家想了解的话,可以看一下Fluent NHibernate API Document。

  在这里顺带介绍一下,MappingConfiguration.ExportTo(string path) 方法,它能把你的Entity Mapping自动生成hbm.xml文件到你指定的path中,我们可以生成好hbm.xml文件,自己再看一篇,看看NHibernate的映射方式,所以是非常好的一个方法,我有时候做映射的时候,遇到问题都会生成出来,随时查看问题所在,所以说是非常有用的一个方法,而且你可以把你的映射文件直接用到NHibernate项目中去。

 

[TestMethod] 
public void NHibernateFactory() 
{ 
  var factory = TradSessionFactory.GetCurrentFactory(); 
  using (ISession session = factory.OpenSession()) 
  { 
    Product product = new Product(); 
    product.CreateTime = DateTime.Now; 
    product.Name = "First Product"; 
    product.Price = 15; 
 
    session.Save(product); 
  } 
} 
 
[TestMethod] 
public void FluentFactory() 
{ 
  var factory = FluentSessionFactory.GetCurrentFactory(); 
  using (var session = factory.OpenSession()) 
  { 
    Product product = session.Load<Product>(1); 
    Assert.AreEqual("First Product", product.Name); 
  } 
}
如果我们的映射都正确,这2个单元测应该会都通过,接下来我们看下测试结果:



正如我们预料的一样,测试通过,说明我们的映射没有出现错误。

  二、使用自定义类型映射实体属性

  NHibernate支持我们用自定义的类型来映射属性,但因为我是初学,我真的不会,当然我在网上找到了相关的资料,在此也不多说,就说说Fluent的方式吧,在我映射自定义属性的时候,也就是Map()的时候,我想看看Map还有哪些方法,结果就看到了CustomTypeIs() 和 CustomTypeIs<T>() 两个方法,一个使用反射,一个用泛型,强类型,我当然会选择后者咯。为了接下来的方便,我把Fluent的Mapping都生成到我传统方式的Mapping目录中,加入到项目,设置成嵌入的资源,一切都为了以后的教程,换句话说以后的教程中,我一般都会使用Fluent来进行映射,而传统方式作为学习之用。

  在Order实体中,我们看到了订单状态我用了OrderState枚举类型,数据库存储类型为tinyint,对于它的映射,我们只需要:

public class OrderMap : ClassMap<Order> 
{ 
  public OrderMap() 
  { 
    Id(p => p.OrderID); 
    Map(p => p.Price); 
    Map(p => p.State).CustomTypeIs<OrderState>(); 
    Map(p => p.CreateTime); 
  } 
}





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值