摘要
NHibernate一对一关系虽然不经常碰到,但是在对于数据库结构优化的时候,经常会碰到一对一关系。比如,产品详细信息比较多的时候,可以把产品详细信息放到另一张表里面,Product主表只记录产品主要信息。这样能够显著提高产品的查询效率。
这篇文章的附件:NHibernate Demo下载。
1、建立ProductDetail表
这里将ProductId设置为主键。
Product和ProductDetail之间的关系。
ProductId既是主键又是外键。
创建ProductDetail的SQL语句
USE [NHibernateDemoDB] GO /****** Object: Table [dbo].[ProductDetail] Script Date: 07/22/2016 23:02:25 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[ProductDetail]( [Id] [int] IDENTITY(1,1) NOT NULL, [ProductId] [int] NOT NULL, [Description] [nvarchar](1000) NOT NULL, CONSTRAINT [PK_ProductDetail] PRIMARY KEY CLUSTERED ( [ProductId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO ALTER TABLE [dbo].[ProductDetail] WITH CHECK ADD CONSTRAINT [FK_ProductDetail_Product] FOREIGN KEY([ProductId]) REFERENCES [dbo].[Product] ([Id]) GO ALTER TABLE [dbo].[ProductDetail] CHECK CONSTRAINT [FK_ProductDetail_Product] GO
2、创建ProductDetail类,修改Product类
ProductDetail类
1 namespace Demo.XML.Entities.Domain 2 { 3 public class ProductDetail 4 { 5 public virtual int Id { get; set; } 6 public virtual string Description { get; set; } 7 public virtual Product Product { get; set; } 8 } 9 }
修改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 public virtual ProductDetail ProductDetail { get; set; } 23 24 public virtual void SetDetailInfo(ProductDetail detail) 25 { 26 this.ProductDetail = detail; 27 detail.Product = this; 28 } 29 } 30 }
Product和ProductDetail双向关联。
3、添加ProductDetail.hbm.xml文件,修改Product.hbm.xml文件
ProductDetail.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="ProductDetail" table="ProductDetail"> <id name="Id"> <generator class="native" /> </id> <property name="Description" not-null="true"/> <many-to-one name="Product" unique="true" column="ProductId"/> </class> </hibernate-mapping>
从表ProductDetail到主表Product这里设置成many-to-one关系,unique="true"表示这个这个Product属性是唯一键,column指出对应的数据库列名。
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> <one-to-one name="ProductDetail" cascade="all" /> </class> </hibernate-mapping>
一对一关联使用one-to-one进行映射。这里配置成从主表Product到从表ProductDetail的级联关系为all,从表到主表没有设置级联关系。
4、关联关系的添加修改和删除
修改Main函数
1 using Demo.Service; 2 using Demo.Service.Interface; 3 using Demo.XML.Entities.Domain; 4 using System; 5 6 namespace Demo.ConsoleApp 7 { 8 class Program 9 { 10 static readonly IProductService productService = new ProductService(); 11 12 static void Main(string[] args) 13 { 14 HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize(); 15 16 ProductDetail detail = new ProductDetail { Description = "This is a very good product" }; 17 Product product = new Product { ProductCode = "3333", ProductName = "orange" }; 18 product.SetDetailInfo(detail); 19 20 int productId = productService.Save(product); 21 22 product.ProductDetail.Description = "This is an excellent product"; 23 productService.Update(product); 24 25 productService.Delete(productId); 26 27 Console.WriteLine("Completed"); 28 Console.ReadLine(); 29 } 30 } 31 }
执行该程序,得到监控结果
从监控结果看到NHibernate正确维护了表之间的一对一关系。