丹尼大叔

数学专业毕业,爱上编程的大叔,兴趣广泛。使用博客园这个平台分享我工作和业余的学习内容,以编程交友。有朋自远方来,不亦乐乎。

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

摘要

NHibernate的多对多关系映射由many-to-many定义。

从这里下载本文的代码NHibernate Demo

1、修改数据库

添加Product表

添加ProductOrder表

数据库表之间的关系:

Product和Order之间的关系是多对多关系,一条订单上有多个产品,一个产品可以有多个订单。多对多关系中的中间表(这里是ProductOrder表)不需要在关系映射中定义实体类和映射文件。

实际项目中,Product和Order之间应该不是这种简单的多对多关系,而是有个“订单明细”的表OrderDetail,记录了明细记录里产品的数量,单价等信息。如下图:

OrderDetail表:

数据库表之间的关系:

Order和OrderDetail之间,以及Product和OrderDetail之间是两个一对多关系。

作为示例,使用ProductOrder表演示怎么实现多对多关系映射。

实际项目中,角色和用户之间的关系就是典型的多对多关系。

2、修改实体类文件

添加Product类

 1 using System.Collections.Generic;
 2 
 3 namespace Demo.XML.Entities.Domain
 4 {
 5     public class Product
 6     {
 7         public Product()
 8         {
 9             Orders = new List<Order>();
10         }
11 
12         public virtual int Id { get; set; }
13 
14         public virtual string ProductCode { get; set; }
15 
16         public virtual string ProductName { get; set; }
17 
18         public virtual string Description { get; set; }
19 
20         public virtual IList<Order> Orders { get; set; }
21     }
22 }

修改Order类

 1 using System;
 2 using System.Collections.Generic;
 3 
 4 namespace Demo.XML.Entities.Domain
 5 {
 6     public class Order
 7     {
 8         public Order()
 9         {
10             Products = new List<Product>();
11         }
12         public virtual int Id { get; set; }
13         public virtual DateTime Ordered { get; set; }
14         public virtual DateTime? Shipped { get; set; }
15         public virtual Address ShipTo { get; set; }
16         public virtual Customer Customer { get; set; }
17         public virtual IList<Product> Products { get; set; }
18     }
19 }

3、修改映射文件

添加Product.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Demo.XML.Entities" namespace="Demo.XML.Entities.Domain">
  <class name="Product" table="Product">
    <id name="Id">
      <generator class="native"/>
    </id>
    <property name="ProductCode" not-null="true"/>
    <property name="ProductName" not-null="true"/>
    <property name="Description"/>
    <bag name="Orders" table="ProductOrder" cascade="all">
      <key column="ProductId"/>
      <many-to-many class="Order" column="OrderId"/>
    </bag>
  </class>
</hibernate-mapping>

修改Order.hbm.xml文件

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Demo.XML.Entities" namespace="Demo.XML.Entities.Domain">
  <class name="Order" table="`Order`">
    <id name="Id">
      <generator class="native"/>
    </id>
    <property name="Ordered"/>
    <property name="Shipped"/>
    <component name="ShipTo">
      <property name="Street"/>
      <property name="City"/>
      <property name="Province"/>
      <property name="Country"/>
    </component>
    <many-to-one name="Customer" column="CustomerId" cascade="save-update"/>
    <bag name="Products" table="ProductOrder" cascade="all">
      <key column="OrderId"/>
      <many-to-many class="Product" column="ProductId"/>
    </bag>
  </class>
</hibernate-mapping>

注意:Product和Order两边都设置了cascade="all"。这样,不管从哪边Product或者Order对数据进行添加、修改、删除都能够进行级联更新。

因为是用IList作为级联属性的类型,所以在映射文件里用Bag属性。

这里同样的是使用了双向关联。两个映射文件的Bag属性内容刚好是“对称性”的。

4、添加接口IProductService和类ProductService,修改Program.cs文件

在Program类添加静态属性productService。

static readonly IProductService productService = new ProductService();

修改Main函数

 1         static void Main(string[] args)
 2         {
 3             HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize();
 4 
 5             var product = new Product
 6             {
 7                 ProductName = "apple",
 8                 ProductCode = "1111",
 9                 Orders = new List<Order>
10                 {
11                     new Order {
12                         Ordered = DateTime.Now
13                     }
14                 }
15             };
16             productService.Save(product);
17 
18             Console.WriteLine("Completed");
19             Console.ReadLine();
20         }

执行程序,得到类似下图的监控结果。

读者可以自己尝试添加Order对象。

删除和修改请读者自己尝试吧,贴代码和图片太繁琐了。

 

posted on 2016-07-10 13:31  丹尼大叔  阅读(631)  评论(0编辑  收藏  举报