首页 > 其他分享 >八、NHibernate关系之——多对多

八、NHibernate关系之——多对多

时间:2022-12-08 11:05:05浏览次数:41  
标签:关系 Product set get virtual Order NHibernate public


多对多关系

废话不多说,看图:


八、NHibernate关系之——多对多_generator

这里我们主要是要解决Order表和Product表之间的多对多的关系,相信有过数据库设计经验的人是很容易理解的,OrderProduct是一个关系表,而Order和Product表都是实体表,在数据库中多对多的的实体关系都通过在两个实体间增加一个关系表来解决,如下:

 

八、NHibernate关系之——多对多_assembly_02

通过在NHibernate中配置Order和Product之间的关系,我们可以直接还原这两个表之间本来的关系(比如:我们可以这样访问order.products.count来获取某个订单下有多少个产品,或者product.orders.count来查看某个产品有多少个订单是定了的,这样是不是很符合我们的思维,更有助于我们对业务的理解),而如果使用SQL的话,我们必须通过它们之间的关系表来获取他们之间的关系,配置后这些都可以交由NHibernate来自动完成了。

 

一、编写Product表对应的实体类和hbm映射文件

Product.cs代码如下:

namespace Model.Entities
{
public class Product
{
public virtual Int32 ProductId { get; set; }
public virtual string Name { get; set; }
public virtual decimal Cost { get; set; }
}
}

Product.hbm.xml代码如下:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Model" namespace="Model.Entities">
<class name="Model.Entities.Product,Model" table="Product">
<id name="ProductId" column="ProductId" type="Int32" unsaved-value="0">
<generator class="native"/>
</id>
<property name="Name" column="Name" type="string" length="50" not-null="true"/>
<property name="Cost" column="Cost" type="decimal" not-null="true"/>
</class>
</hibernate-mapping>

 

二、修改Order表对应的实体类和hbm映射文件

Order.cs修改如下:

namespace Model.Entities
{
public class Order
{
public virtual Int32 OrderId { get; set; }
public virtual DateTime OrderDate { get; set; }
//public virtual Int32 Customer { get; set; }
//一个order是属于一个customer的
public virtual Customer Customer { get; set; }
//多对多一个Order可以拥有多个Products
public virtual IList<Product> Products { get; set; }
}
}

Order.hbm.xml修改如下:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Model" namespace="Model.Entities">
<!--注意:下面的table="[Order]"属性,这是因为Order是sql中的关键字,如果不用[]括起来,将会在执行时报错,大家在到时可以试试-->
<class name="Model.Entities.Order,Model" table="[Order]">
<id name="OrderId" column="OrderId" type="Int32" unsaved-value="0">
<generator class="native"/>
</id>
<property name="OrderDate" column ="OrderDate" type="DateTime" not-null="false"></property>
<!--同样请注释掉Customer属性-->
<!--<property name="Customer" column="Customer" type="Int32" not-null="false"></property>-->

<!--一个order属于一个Customer-->
<many-to-one name="Customer" column="Customer" not-null="true" class="Model.Entities.Customer,Model" foreign-key="FK_CustomerOrders"/>

<!--多对多,一个Order有多个Products,这里配置的意思是,OrderProduct表中一个key字段即[Order]字段对应多个Product-->
<bag name="Products" generic="true" table="OrderProduct"><!—name_对应Order.cs中的Products属性、table_关系表-->
<key column="[Order]" foreign-key="FK_OrderProducts"/><!—column_OrderProduct表的字段_外键、foreign-key_关系名称,FK_是必须的-->
<many-to-many column="Product" class="Model.Entities.Product,Model" foreign-key="FK_ProductOrders"/><!—column_OrderProduct表的字段_外键-->
</bag>
</class>
</hibernate-mapping>

 

三、修改Product表对应的实体类和hbm映射文件

Product.cs修改如下:

namespace Model.Entities
{
public class Product
{
public virtual Int32 ProductId { get; set; }
public virtual string Name { get; set; }
public virtual decimal Cost { get; set; }
//多对多一个Product可以属于多个Orders
public virtual IList<Order> Orders { get; set; }
}


Product.hbm.xml修改如下:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Model" namespace="Model.Entities">
<class name="Model.Entities.Product,Model" table="Product">
<id name="ProductId" column="ProductId" type="Int32" unsaved-value="0">
<generator class="native"/>
</id>
<property name="Name" column="Name" type="string" length="50" not-null="true"/>
<property name="Cost" column="Cost" type="decimal" not-null="true"/>

<!--多对多,解释可以参考上面Order.hbm.xml的注释-->
<bag name="Orders" generic="true" table="OrderProduct">
<key column="Product" foreign-key="FK_ProductOrders"/>
<many-to-many column="[Order]" class="Model.Entities.Order,Model" foreign-key="FK_OrderProducts"/>
</bag>
</class>
</hibernate-mapping>

 

四、为相关表添加关联数据

数据可以由自己添加,这里提供一个参考:

 

八、NHibernate关系之——多对多_class_03

 


五、编写DAL(数据访问层、持久层)方法来关联查询CustomerOrderOrderProductProduct

方法可以放在旧有的文件里面,也可以放在新建的文件里面,具体参考前面的DAL层的相关文件,代码如下:

    

//关联查询——多对多
public IList<Customer> GetCustomersWithOrdersAndProducts(DateTime
{
IList<Customer> customers = null;

//用SQL查询
//customers = session
// .CreateSQLQuery("select distinct customer.* from Customer customer inner join [Order] o on o.Customer=customer.CustomerId inner join OrderProduct op on o.OrderId=op.[Order] inner join Product p on op.Product=p.ProductId where o.OrderDate< :orderDate")
// .AddEntity("customer", typeof(Customer))
// .SetDateTime("orderDate", orderDate)
// .List<Customer>();

            /*因为在映射文件已经定义实体之间一对多、多对多关系,NHibernate通过映射文件知道如何去关联这些实体,我们不需要在查询

            语句中重复定义。这里使用查询和上一篇使用HQL关联查询语句一样,NHibernate完全可以去关联对象,实现查询订单和产品。

,不过我没看明白,先继续吧,以后再看看*/

    

//用HQL查询
customers = session
.CreateQuery("select distinct c from Customer c inner join c.Orders o where o.OrderDate<=:orderDate")
.SetDateTime("orderDate", orderDate)
.List<Customer>();

return
}

注意:上面的方法中提供了两种查询方式,一种是SQL查询、一种是HQL查询,当你使用其中一种时,请注释掉另外一种,以确保测试的准确性;

 

六、编写DAL.Test项目中的测试方法

方法可以放在旧有的文件里面,也可以放在新建的文件里面,具体参考前面的DAL.Test层的相关文件,代码如下:

      

[Test]
public void
{
IList<Customer> customers = sample.GetCustomersWithOrdersAndProducts(DateTime.Now);
}

在函数中设置一个断点,然后在“即时窗口”输入代码如下:

 

八、NHibernate关系之——多对多_assembly_04

要访问Customer的属性就OK但是要访问Order的熟悉就只能访问Count,其它的属性不能访问。

 

七、小宇宙爆发——访问关联对象及其属性

上面的截图我们可以看到,这里无法通过customer关联访问其order对象,这是因为我不会用ISet集合,好吧!既然我不会用就改用IList吧,不过要做小小的修改,如下:

Customer.cs修改如下:

 

//注意,实体类必须为public,否则无法访问
public class Customer
{
//在NHibernate的实体类中,所有的公共方法、属性和事件都必须使用virtual修饰
public virtual int CustomerId { get; set; }
public virtual string Firstname { get; set; }
public virtual string Lastname { get; set; }
//一个Customer有多个Order
//public virtual ISet<Order> Orders { get; set; } //ISet在映射文件中对应Set配置节
public virtual IList<Order> Orders { get; set; } //IList在映射文件中对应bag配置节
}

Customer.hbm.xml修改如下:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Model" namespace="Model.Entities">
<class name="Model.Entities.Customer,Model" table="Customer">
<id name="CustomerId" column="CustomerId" type="Int32" unsaved-value="0">
<generator class="native"></generator>
</id>

<property name="Firstname" column="Firstname" type="string" length="50" not-null="false"></property>
<property name="Lastname" column="Lastname" type="string" length="50" not-null="false"></property>

<!--一个Customer对应多个order-->
<!--<set name="Orders" table="[Order]" generic="true" inverse="true">
<key column="Customer" foreign-key="FK_CustomerOrders"/>
<one-to-many class="Model.Entities.Order,Model"/>
</set>-->
<bag name="Orders" table="[Order]" generic="true" inverse="true">
<key column="Customer" foreign-key="FK_CustomerOrders"/>
<one-to-many class="Model.Entities.Order,Model"/>
</bag>
</class>
</hibernate-mapping>

 

在函数GetCustomers()中设置一个断点,然后在“即时窗口”输入代码如下:

 

八、NHibernate关系之——多对多_assembly_05

从上面的代码我们可以看到,我们可以随意的访问关联对象及其属性,hoho~~还是IList好用。

 

 

标签:关系,Product,set,get,virtual,Order,NHibernate,public
From: https://blog.51cto.com/u_15906220/5920734

相关文章

  • NHibernate学习笔记
    NHibernate学习笔记 一、         什么是NHibernate、为什么要用它及相关资源 二、         第一个NHibernate程序 三、         NHibern......
  • 十三、NHibernate之对象状态
     引入​在程序运行过程中使用对象的方式对数据库进行操作,这必然会产生一系列的持久化类的实例对象。这些对象可能是刚刚创建并准备存储的,也可能是从数据库中查询的,为了区分......
  • 十二、NHibernate之SchemaExport工具
    说明​使用领域驱动开发,我觉得还不太实际,或者说对于我来说条件还不成熟,因为我对NHibernate还不太熟悉,就现时来说,使用数据库驱动开发还是最好的选择,所以,我这里暂时先不管Sche......
  • 看俩个特征是否存在线性关系。
    importpandasaspdimportseabornassnsimportmatplotlib.pyplotaspltfromscipyimportstatstrain_data='zhengqi_train.txt'test_data='zhengqi_test.txt'......
  • 推理判断第三章,第二小节 逻辑关系
    考点a>全同关系b>包容关系c>并列关系d>交叉关系e>对应关系 1.全同关系a>指两次词表达的意思完全相同,如土豆和马铃薯,麦克风和话筒......
  • .NET中各个框架的关系
    .NET5及以上版本是.NETFramework和.NETCore统称。在.NETFramework4.8以后,微软不再对Farmwork框架进行更新但仍提供技术支持;在跨平台的.NETCore3.1以后,避免和.NETF......
  • 数据库设计逻辑方向踩坑 表关系 2022-12-6
    数据库设计逻辑方向踩坑表关系2022-12-6当时设计表结构用户表与酒局表关联,酒局内有多个用户,且用户的饮酒类型与酒局表关联关键点:酒局会被预约,用户饮酒类型......
  • 数据量大小和模型大小之间的关系
    作者:Henry链接:https://zhuanlan.zhihu.com/p/539233251来源:知乎1、从模型方面考虑。举例说明:本身问题是二次的,用线性模型处理问题就是欠拟合,用三次及更高次处理问题就是......
  • UML的六种关系-系统学习四
    一、背景介绍众所周知设计模式是程序界的内功心法,那么这内功心法中包含UML图(宏观部分)、场景(场段)、代码(实操),UML图中最重要的元素当属六大关系了至此有了小编的这边总结......
  • Hadoop和Hive的关系
    Hadoop和Hive的关系1.Hadoop是一个能够对大量数据进行分布式处理的软件框架。Hadoop最核心的设计就是hdfs和mapreduce,hdfs提供存储,mapreduce用于计算。2.Hive是Hadoop的延......