每个类型的NHibernate表从现有父级持久化子级
我有两个类,每个类型的NHibernate表从现有父级持久化子级,nhibernate,inheritance,fluent-nhibernate,persistence,fluent-nhibernate-mapping,Nhibernate,Inheritance,Fluent Nhibernate,Persistence,Fluent Nhibernate Mapping,我有两个类,Member.cs和Customer.cs,并使用所描述的每种类型的表继承映射 这带来了同样的问题,但没有答案 Customer.cs public class Customer { } public class Member : Customer { public Member(Customer customer) { CreateFromCustomer(customer); } private void CreateFromC
Member.cs
和Customer.cs
,并使用所描述的每种类型的表继承映射
这带来了同样的问题,但没有答案
Customer.cs
public class Customer
{
}
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;
}
}
public class CustomerMap : ClassMap<Customer>
{
public CustomerMap()
{
Id(x => x.Id)
.GeneratedBy.GuidComb();
}
}
public class MemberMap : SubclassMap<Member>
{
public MemberMap()
{
KeyColumn("Id");
}
}
[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();
}
}
Member.cs
public class Customer
{
}
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;
}
}
public class CustomerMap : ClassMap<Customer>
{
public CustomerMap()
{
Id(x => x.Id)
.GeneratedBy.GuidComb();
}
}
public class MemberMap : SubclassMap<Member>
{
public MemberMap()
{
KeyColumn("Id");
}
}
[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();
}
}
CustomerMap.cs
public class Customer
{
}
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;
}
}
public class CustomerMap : ClassMap<Customer>
{
public CustomerMap()
{
Id(x => x.Id)
.GeneratedBy.GuidComb();
}
}
public class MemberMap : SubclassMap<Member>
{
public MemberMap()
{
KeyColumn("Id");
}
}
[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
这是预期的行为吗
我理解如果我们想从一个临时父对象创建一个子对象,这是一个正确的行为
但是,如果我们要创建一个引用现有父对象的子对象呢
我提供的链接没有涵盖任何持久性示例,谷歌也没有。简短回答
不,不可能将已持久化的对象“升级”到其子类。Nhibernate根本不支持这一点。这就是为什么您会看到两个客户和一个会员条目。这实际上是预期的行为,因为Nhibernate只是使用对象的新ID创建一个副本,而不是创建对成员的引用
所以基本上你可以做任何一件事
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);
}
}
这将在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();
}
使用(var session=NHibernateSessionFactory.Current.OpenSession())
{
session.Save(新客户()
{
Name=“客户A”
});
session.Flush();
}
使用(var session=NHibernateSessionFactory.Current.OpenSession())
{
var customer=session.Query().FirstOrDefault();
//var成员=作为成员的客户;
var成员=新成员()
{
Name=customer.Name,
MemberSpecificProperty=“其他内容”
};
删除(客户);
会议.保存(成员);
session.Flush();
}
我之前确实尝试过这种方法,但我有一些担心:关于Id引用,因为成员来自客户,所以他们有相同的Id生成策略,Generated.Guid说。当我从现有的Customer.Id中分配Member.Id时会发生什么情况?该Id是持久化的,还是生成了新的Id?我关心的是,如果客户需要在这里安装IList,该怎么办。而且真正删除一个客户也很麻烦,因为我基本上喜欢Cascade。所有的策略都是为了持久化新的实体。但是如果有必要,我愿意改为Cascade.SaveUpdate。正如我所写的,您不能重用已存储的ID为A的客户来创建ID为A的成员,nHibernate将生成一个新的ID B,并将客户+成员行存储在ID为B的数据库中。那么,当存在引用现有客户的其他数据时,如何解决该问题?它们也应该被重新创造吗?对整个对象图进行重新创建需要大量的工作。@SamuelAdam是的,正如我所写的,重新创建、使用不同的对象策略或使用本机sql。如果这是应用程序中常见的场景,我建议使用不同的策略。意思是不让成员从客户继承。。。简单地建立一对一的关系就可以了,因为这意味着每个客户可能都必须有一个成员