我试图让NHibernate在一对一的映射方案中保存完整的对象图。我有以下课程
public class Employee : EntityBase
{
public virtual string EmployeeNumber { get; set; }
public virtual Address ResidentialAddress {get; set; }
}
public class Address : EntityBase
{
public virtual string AddressLine1 { get; set; }
public virtual string AddressLine2 { get; set; }
public virtual string Postcode { get; set; }
public virtual string City { get; set; }
public virtual string Country { get; set; }
public virtual Employee Employee { get; set; }
}
我试图在此处使用一对一映射,以便一名员工只有一个居住地址。我的对应关系如下
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Domain" namespace="Domain">
<class name="Employee">
<id name="Id" generator="hilo" />
<property name="EmployeeNumber" length="10" />
<one-to-one name="ResidentialAddress" class="Address" property-ref="Employee" cascade="all" />
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Domain" namespace="Domain">
<class name="Address">
<id name="Id" generator="hilo" />
<property name="AddressLine1"/>
<property name="AddressLine2" />
<property name="Postcode" />
<property name="City" />
<property name="Country" />
<many-to-one name="Employee" class="Employee" unique="true" />
</class>
</hibernate-mapping>
我正在使用以下代码来保存员工对象的实例
using (var transaction = Session.BeginTransaction())
{
id = Session.Save(new Employee
{
EmployeeNumber = "123456789",
ResidentialAddress = new Address
{
AddressLine1 = "Address line 1",
AddressLine2 = "Address line 2",
Postcode = "postcode",
City = "city",
Country = "country"
}
});
transaction.Commit();
}
在上述情况下,Address上返回给Employee的外键始终为空。但是,如果我ResidentialAddress
在Employee
类上更改R属性,以便Employee
始终按如下所示正确填充该属性
private Address address;
public virtual Address ResidentialAddress
{
get { return address; }
set
{
address = value;
if (value != null) value.Employee = this;
}
}
这使其完美工作。为什么要设置ResidentialAddress.Employee
?我在映射中缺少什么吗?NHibernate是否应该不自动保存完整的对象图(并因此确定适当的外键值)。
上面的工作代码使我担心,因为在从数据库加载实体期间从NHiberante调用它时可能会产生问题。
您没有丢失任何东西。
我们(开发人员)应始终关心设置任何双向关系的两端。
当我们使用one-to-many
(不使用inverse =“ true”)并且不设置时many-to-one
,我们总是以冗余且效率低下的SQL语句序列结束:
不建议这样做:6.8。双向关联:
...非反面用于将内存中的表示形式保存到数据库中。如果两者都会触发更改,我们将得到不必要的INSERT / UPDATE甚至可能是外键冲突!双向一对多关联当然也是如此...
因此,这是一对多,多对一的。
一对一的情况
如上所述,没有适当的收集持久性。中间没有人,这会照顾到另一端,并发出“无效”的INSERT和更高版本的UPDATE。NHibernate的将使用标准的实体,持久的Employee
和Address
。
关系的每个关联端(员工地址)都有其自己的持久器。这些可以级联触发(通常有个好主意<one-to-one ... cascade="all" />
)
但是每个持久程序都需要足够的信息来创建正确的INSERT或UPDATE语句。即,即使C#地址也必须了解其雇员。Address持久程序将仅处理INSERT / UPDATE,并且只能访问Address实例。
简介:我们必须在代码中设置两端。...即使我们没有被迫(带有可为空的父列的非反向子映射),这也是一个好习惯。
BTW:一旦从数据库加载,我们预计这NHibernate的将设置两个两端......为什么我们不应该做?
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句