• NHibernate系列文章十九:NHibernate关系之多对多关系(附程序下载)


    摘要

    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对象。

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

  • 相关阅读:
    Json对象与Json字符串互转(4种转换方式)
    Web.config配置文件详解
    jQuery BlockUI Plugin Demo 6(Options)
    jQuery BlockUI Plugin Demo 5(Simple Modal Dialog Example)
    jQuery BlockUI Plugin Demo 4(Element Blocking Examples)
    jQuery BlockUI Plugin Demo 3(Page Blocking Examples)
    jQuery BlockUI Plugin Demo 2
    <configSections> 位置引起的错误
    关于jQuery的cookies插件2.2.0版设置过期时间的说明
    jQuery插件—获取URL参数
  • 原文地址:https://www.cnblogs.com/uncle_danny/p/5657543.html
Copyright © 2020-2023  润新知