zoukankan      html  css  js  c++  java
  • 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对象。

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

  • 相关阅读:
    OP_REQUIRES failed at conv_ops.cc:386 : Resource exhausted: OOM when allocating tensor with shape..
    Python中*args和**kwargs的区别
    命令行运行Python脚本时传入参数的三种方式
    关于 initWithNibName 和 loadNibNamed 的区别和联系-iPhone成长之路
    NSBundle介绍
    UIView总结
    iPhone How-to:如何调整UIView的Z-Order
    有关View的几个基础知识点-IOS开发
    NSNumber与NSInteger的区别
    iOS第三方开源库的吐槽和备忘
  • 原文地址:https://www.cnblogs.com/uncle_danny/p/5657543.html
Copyright © 2011-2022 走看看