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类
using System.Collections.Generic; namespace Demo.XML.Entities.Domain
{
public class Product
{
public Product()
{
Orders = new List<Order>();
} public virtual int Id { get; set; } public virtual string ProductCode { get; set; } public virtual string ProductName { get; set; } public virtual string Description { get; set; } public virtual IList<Order> Orders { get; set; }
}
}
修改Order类
using System;
using System.Collections.Generic; namespace Demo.XML.Entities.Domain
{
public class Order
{
public Order()
{
Products = new List<Product>();
}
public virtual int Id { get; set; }
public virtual DateTime Ordered { get; set; }
public virtual DateTime? Shipped { get; set; }
public virtual Address ShipTo { get; set; }
public virtual Customer Customer { get; set; }
public virtual IList<Product> Products { get; set; }
}
}
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函数
static void Main(string[] args)
{
HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); var product = new Product
{
ProductName = "apple",
ProductCode = "",
Orders = new List<Order>
{
new Order {
Ordered = DateTime.Now
}
}
};
productService.Save(product); Console.WriteLine("Completed");
Console.ReadLine();
}
执行程序,得到类似下图的监控结果。

读者可以自己尝试添加Order对象。
删除和修改请读者自己尝试吧,贴代码和图片太繁琐了。
NHibernate系列文章十九:NHibernate关系之多对多关系(附程序下载)的更多相关文章
- NHibernate系列文章十:NHibernate对象二级缓存下
摘要 上一节对NHibernate二级缓存做了简单介绍,NHibernate二级缓存是由SessionFactory管理的,所有Session共享.这一节介绍二级缓存其他两个方面:二级缓存查询和二级缓 ...
- NHibernate系列文章十八:NHibernate关系之一对多(附程序下载)
摘要 这篇文章介绍NHibernate最实用的内容:关系映射. NHibernate的关系映射方式有三种: Set:无序对象集合,集合中每一个元素不能重复. List:有序对象集合,集合中的元素可以重 ...
- NHibernate系列文章十五:NHibernate组件
摘要 前面文章介绍了NHibernate对简单.net数据类型的映射对照表.NHibernate也可以映射复杂数据类型,这里介绍通过组件映射NHibernate值对象. 1. NHibernate引用 ...
- NHibernate系列文章十六:使用程序集管理NHibernate项目(附程序下载)
摘要 在实际的项目中,经常是将NHibernate的实体关系映射类做成独立的工程(assembly dll),只对外提供Session调用的接口.这个程序集作为数据访问层,可以被上面的多个工程(ASP ...
- NHibernate系列文章一:NHibernate介绍
摘要 NHibernate是一个成熟的开源的面向对象的.net映射框架.大量的实际项目中正在使用该框架.他是建立在ADO.Net基础之上.目前的版本是NHibernate 4.0.4.本系列文章都是基 ...
- NHibernate系列文章十七:NHibernate Session管理(附程序下载)
摘要 NHibernate的Session的管理涉及到NHibernate的两个最重要的对象ISessionFactory和ISession.ISessionFactory的生成非常消耗资源,通常都在 ...
- NHibernate系列文章四:NHibernate运行时监控
摘要 有三种方式可以实现NHibernate运行时监控,监控的信息包括:执行了的SQL语句.NHibernate执行过程.数据库性能分析.这对我们学习NHibernate有很大的帮助,在工作中也能快速 ...
- NHibernate系列文章八:NHibernate对象一级缓存
摘要 Nhibernatea缓存非常强大,按照缓存存储在Session对象还是SessionFactory对象分为一级缓存和二级缓存. 一级缓存存在于Session对象里,也叫Session缓存,由S ...
- NHibernate系列文章十二:Load/Get方法
摘要 NHibernate提供两个方法按主键值查找对象:Load/Get. 1. Load/Get方法的区别 Load: Load方法可以对查询进行优化. Load方法实际得到一proxy对象,并不立 ...
随机推荐
- iOS运行时工具-cycript
cycript是大神saurik开发的一个非常强大的工具,可以让开发者在命令行下和应用交互,在运行时查看和修改应用.它确实可以帮助你破解一些应用,但我觉得这个工具主要还是用来学习其他应用的设计(主要是 ...
- Ubuntn系统忘记密码的解决方法(虚拟机下同样处理)
不知道你有没有遇到过忘记了ubuntn系统密码的情况,反正我都了,一段时间没用就很容易忘记密码的,此时无奈只能修改密码了!下面分享一个简单实用的方法: 版本号为: (我用的是V-BOX虚拟机安装的ub ...
- MySQL数据单个数据太大,导入不进去
mysql导入数据,navicat报错: MySQL server has gone away Table Restored: act_ge_bytearray Rolling back... Fin ...
- hdu4686 Arc of Dream ——构造矩阵+快速幂
link: http://acm.hdu.edu.cn/showproblem.php?pid=4686 构造出来的矩阵是这样的:根据题目的ai * bi = ……,可以发现 矩阵1 * 矩阵3 = ...
- c++类的声明和对象的定义---10
原创博客:转载请标明出处:http://www.cnblogs.com/zxouxuewei/ 类是创建对象的模板,一个类可以创建多个对象,每个对象都是类类型的一个变量:创建对象的过程也叫类的实例化. ...
- Android——课堂整理:assets目录和手机外部存储
layout文件: <Button android:layout_width="match_parent" android:layout_height="wrap_ ...
- AFX_MANAGE_STATE(AfxGetStaticModuleState())DLL导出函数包含MFC资源
AFX_MANAGE_STATE(AfxGetStaticModuleState()) 先看一个例子: .创建一个动态链接到MFC DLL的规则DLL,其内部包含一个对话框资源.指定该对话框ID如下: ...
- MySql变量,
http://blog.csdn.net/rdarda/article/details/7878836 1.变量的定义 在Mysql里面可以像我们写代码中一样定义变量来保持中间结果,看下面的格式: [ ...
- CSS 知识点
1:display:block:比较常用于<a><span>这两个标签——因为这两个标签非块元素,如果不用display:block定义一下,因为a标签没有结构,就是没有宽高, ...
- c++读写二进制文件
要读取文件必须包含<fstream>头文件,这里包含了C++读写文件的方法,可以使用fstream 类,这个类可以对文件进行读写操作. 1.打开文件. 打开文件可以有两种方式,第一 ...