我有2个类,Member.cs
和Customer.cs
,并使用每个类型的表继承映射here。
这question提出了同样的问题,但没有回答。
Customer.cs
public class Customer
{
}
Member.cs
public class Member : Customer
{
public Member(Customer customer)
{
CreateFromCustomer(customer);
}
private void CreateFromCustomer(Customer customer)
{
// Here I assume I'll assign the Id so NHibernate wouldn't have to create a new Customer and know what Customer to be referred
Id = customer.Id;
}
}
CustomerMap.cs
public class CustomerMap : ClassMap<Customer>
{
public CustomerMap()
{
Id(x => x.Id)
.GeneratedBy.GuidComb();
}
}
MemberMap.cs
public class MemberMap : SubclassMap<Member>
{
public MemberMap()
{
KeyColumn("Id");
}
}
我尝试了几个测试用例:
Test1.cs
[Test]
public void CanAddCustomer()
{
var customerRepo = /* blablabla */;
using (var tx = NHibernateSessionManager.GetSession().BeginTransaction())
{
var customer = new Customer()
customerRepo.RegisterCustomer(customer);
tx.Commit();
}
using (var tx = NHibernateSessionManager.GetSession().BeginTransaction())
{
/* Get the persisted customer */
var customer = customerRepo.GetCustomerByWhatever();
var member = customerRepo.RegisterMember(new Member(customer));
tx.Commit();
}
}
我期待着:
1位客户和1位成员,该客户是该客户的子女
相反,我有:
2个客户(1个是正确创建的,1个是所有空列)和1个成员,Id引用了所有空列Customer。
这是预期的行为吗?
我理解如果我们想要从瞬态父对象创建子对象,这是正确的行为。
但是如果我们要创建一个引用现有父对象的子对象呢?
我提供的链接并未涵盖任何持久性示例,也没有使用Google搜索。
答案 0 :(得分:2)
不,不可能将已经持久化的对象“升级”到其子类。 Nhibernate根本不支持这个。这就是为什么你看到2个客户和一个成员条目。这实际上是预期的行为,因为Nhibernate只是创建一个带有对象新ID的副本,而不是创建对Member的引用...
所以基本上你可以做任何一次
您的课程可能如下所示
public class Customer
{
public virtual Guid Id { get; set; }
public virtual string Name { get; set; }
}
public class Member : Customer
{
public virtual string MemberSpecificProperty { get; set; }
}
基本上,会员可以拥有其他属性,但也会拥有与原因客户相同的属性。
public class CustomerMap : ClassMap<Customer>
{
public CustomerMap()
{
Id(x => x.Id)
.GeneratedBy.GuidComb();
Map(x => x.Name);
}
}
对于子类,您只需要映射其他属性!
public class MemberMap : SubclassMap<Member>
{
public MemberMap()
{
Map(x => x.MemberSpecificProperty);
}
}
测试它
{
session.Save(new Customer()
{
Name ="Customer A"
});
session.Save(new Member()
{
Name = "Customer B",
MemberSpecificProperty = "something else"
});
session.Flush();
}
这将在customer表中创建2个条目,在Member表中创建一行。所以这是预期的,因为我们创建了一个客户和一个成员......
现在从客户A“升级”到会员:
using (var session = NHibernateSessionFactory.Current.OpenSession())
{
session.Save(new Customer()
{
Name ="Customer A"
});
session.Flush();
}
using (var session = NHibernateSessionFactory.Current.OpenSession())
{
var customer = session.Query<Customer>().FirstOrDefault();
//var member = customer as Member;
var member = new Member()
{
Name = customer.Name,
MemberSpecificProperty = "something else"
};
session.Delete(customer);
session.Save(member);
session.Flush();
}