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


    摘要

    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正确维护了表之间的一对一关系。

  • 相关阅读:
    Apache 配置多站点访问「为项目分配二级域名」
    php封装的mysqli类完整实例
    PHP实现链式操作的三种方法详解
    php实现简单链式操作mysql数据库类
    PHP PDO_MYSQL 链式操作 非链式操作类
    23个数据库常用查询语句
    微信小程序表单弹窗实例
    ES6 && ECMAScript2015 新特性
    ES6新语法概览
    sql将两个日期之间的日子全列出来
  • 原文地址:https://www.cnblogs.com/uncle_danny/p/5697611.html
Copyright © 2020-2023  润新知