NHibernate删除多对多父级和子级
我有三节课公司,地址和办公室。以下是实体定义 公司:NHibernate删除多对多父级和子级,nhibernate,fluent-nhibernate,nhibernate-mapping,fluent-nhibernate-mapping,Nhibernate,Fluent Nhibernate,Nhibernate Mapping,Fluent Nhibernate Mapping,我有三节课公司,地址和办公室。以下是实体定义 公司: public class Company: Identity { public Company() { Offices = Offices ?? new List<Office>(); } public virtual string Name { get; set; } public virtual IList<Office> Offices { get; set
public class Company: Identity
{
public Company()
{
Offices = Offices ?? new List<Office>();
}
public virtual string Name { get; set; }
public virtual IList<Office> Offices { get; set; }
public virtual void AddOffice(Office office)
{
office.Company = this;
Offices.Add(office);
}
}
public class Address: Identity
{
public Address()
{
CompanyOffices = CompanyOffices ?? new List<Office>();
}
public virtual string FullAddress { get; set; }
public virtual IList<Office> CompanyOffices { get; set; }
}
public class Office: Identity
{
public Office()
{
Company = Company ?? new Company();
Address = Address ?? new Address();
}
public virtual Company Company { get; set; }
public virtual Address Address { get; set; }
public virtual bool IsHeadOffice { get; set; }
}
public class CompanyMapping: IdentityMapping<Company>
{
public CompanyMapping()
{
Map(x => x.Name);
HasMany(x => x.Offices).KeyColumn("CompanyId").Inverse().Cascade.AllDeleteOrphan();
}
}
public class AddressMapping: IdentityMapping<Address>
{
public AddressMapping()
{
Map(x => x.FullAddress);
HasMany(x => x.CompanyOffices).KeyColumn("AddressId").Inverse().Cascade.All();
}
}
public class OfficeMapping: IdentityMapping<Office>
{
public OfficeMapping()
{
Map(x => x.IsHeadOffice);
References(x => x.Company).Column("CompanyId").Cascade.None();
References(x => x.Address).Column("AddressId").Cascade.All();
}
}
var sessionFactory = CreateSessionFactory();
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
var companyOne = new Company { Name = "Company One" };
var companyTwo = new Company { Name = "Company Two" };
var addressOne = new Address { FullAddress = "Address One" };
var addressTwo = new Address { FullAddress = "Address Two" };
var officeOne = new Office { Company = companyOne, Address = addressOne, IsHeadOffice = true };
var officeTwo = new Office { Company = companyTwo, Address = addressTwo, IsHeadOffice = false };
var officeThr = new Office { Company = companyOne, Address = addressTwo, IsHeadOffice = true };
companyOne.AddOffice(officeOne);
companyTwo.AddOffice(officeTwo);
companyOne.AddOffice(officeThr);
session.SaveOrUpdate(companyOne);
session.SaveOrUpdate(companyTwo);
transaction.Commit();
}
}
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
var companyOne = session.Get<Company>((long)1);
session.Delete(companyOne);
transaction.Commit();
}
}
现在,对于这些类,我有以下映射
公司映射:
public class Company: Identity
{
public Company()
{
Offices = Offices ?? new List<Office>();
}
public virtual string Name { get; set; }
public virtual IList<Office> Offices { get; set; }
public virtual void AddOffice(Office office)
{
office.Company = this;
Offices.Add(office);
}
}
public class Address: Identity
{
public Address()
{
CompanyOffices = CompanyOffices ?? new List<Office>();
}
public virtual string FullAddress { get; set; }
public virtual IList<Office> CompanyOffices { get; set; }
}
public class Office: Identity
{
public Office()
{
Company = Company ?? new Company();
Address = Address ?? new Address();
}
public virtual Company Company { get; set; }
public virtual Address Address { get; set; }
public virtual bool IsHeadOffice { get; set; }
}
public class CompanyMapping: IdentityMapping<Company>
{
public CompanyMapping()
{
Map(x => x.Name);
HasMany(x => x.Offices).KeyColumn("CompanyId").Inverse().Cascade.AllDeleteOrphan();
}
}
public class AddressMapping: IdentityMapping<Address>
{
public AddressMapping()
{
Map(x => x.FullAddress);
HasMany(x => x.CompanyOffices).KeyColumn("AddressId").Inverse().Cascade.All();
}
}
public class OfficeMapping: IdentityMapping<Office>
{
public OfficeMapping()
{
Map(x => x.IsHeadOffice);
References(x => x.Company).Column("CompanyId").Cascade.None();
References(x => x.Address).Column("AddressId").Cascade.All();
}
}
var sessionFactory = CreateSessionFactory();
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
var companyOne = new Company { Name = "Company One" };
var companyTwo = new Company { Name = "Company Two" };
var addressOne = new Address { FullAddress = "Address One" };
var addressTwo = new Address { FullAddress = "Address Two" };
var officeOne = new Office { Company = companyOne, Address = addressOne, IsHeadOffice = true };
var officeTwo = new Office { Company = companyTwo, Address = addressTwo, IsHeadOffice = false };
var officeThr = new Office { Company = companyOne, Address = addressTwo, IsHeadOffice = true };
companyOne.AddOffice(officeOne);
companyTwo.AddOffice(officeTwo);
companyOne.AddOffice(officeThr);
session.SaveOrUpdate(companyOne);
session.SaveOrUpdate(companyTwo);
transaction.Commit();
}
}
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
var companyOne = session.Get<Company>((long)1);
session.Delete(companyOne);
transaction.Commit();
}
}
公共类公司映射:标识映射
{
上市公司映射()
{
Map(x=>x.Name);
HasMany(x=>x.Offices).KeyColumn(“CompanyId”).Inverse().Cascade.AllDeleteOrphan();
}
}
地址映射:
public class Company: Identity
{
public Company()
{
Offices = Offices ?? new List<Office>();
}
public virtual string Name { get; set; }
public virtual IList<Office> Offices { get; set; }
public virtual void AddOffice(Office office)
{
office.Company = this;
Offices.Add(office);
}
}
public class Address: Identity
{
public Address()
{
CompanyOffices = CompanyOffices ?? new List<Office>();
}
public virtual string FullAddress { get; set; }
public virtual IList<Office> CompanyOffices { get; set; }
}
public class Office: Identity
{
public Office()
{
Company = Company ?? new Company();
Address = Address ?? new Address();
}
public virtual Company Company { get; set; }
public virtual Address Address { get; set; }
public virtual bool IsHeadOffice { get; set; }
}
public class CompanyMapping: IdentityMapping<Company>
{
public CompanyMapping()
{
Map(x => x.Name);
HasMany(x => x.Offices).KeyColumn("CompanyId").Inverse().Cascade.AllDeleteOrphan();
}
}
public class AddressMapping: IdentityMapping<Address>
{
public AddressMapping()
{
Map(x => x.FullAddress);
HasMany(x => x.CompanyOffices).KeyColumn("AddressId").Inverse().Cascade.All();
}
}
public class OfficeMapping: IdentityMapping<Office>
{
public OfficeMapping()
{
Map(x => x.IsHeadOffice);
References(x => x.Company).Column("CompanyId").Cascade.None();
References(x => x.Address).Column("AddressId").Cascade.All();
}
}
var sessionFactory = CreateSessionFactory();
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
var companyOne = new Company { Name = "Company One" };
var companyTwo = new Company { Name = "Company Two" };
var addressOne = new Address { FullAddress = "Address One" };
var addressTwo = new Address { FullAddress = "Address Two" };
var officeOne = new Office { Company = companyOne, Address = addressOne, IsHeadOffice = true };
var officeTwo = new Office { Company = companyTwo, Address = addressTwo, IsHeadOffice = false };
var officeThr = new Office { Company = companyOne, Address = addressTwo, IsHeadOffice = true };
companyOne.AddOffice(officeOne);
companyTwo.AddOffice(officeTwo);
companyOne.AddOffice(officeThr);
session.SaveOrUpdate(companyOne);
session.SaveOrUpdate(companyTwo);
transaction.Commit();
}
}
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
var companyOne = session.Get<Company>((long)1);
session.Delete(companyOne);
transaction.Commit();
}
}
public类地址映射:IdentityMapping
{
公共地址映射()
{
映射(x=>x.FullAddress);
HasMany(x=>x.CompanyOffices).KeyColumn(“AddressId”).Inverse().Cascade.All();
}
}
办公室映射:
public class Company: Identity
{
public Company()
{
Offices = Offices ?? new List<Office>();
}
public virtual string Name { get; set; }
public virtual IList<Office> Offices { get; set; }
public virtual void AddOffice(Office office)
{
office.Company = this;
Offices.Add(office);
}
}
public class Address: Identity
{
public Address()
{
CompanyOffices = CompanyOffices ?? new List<Office>();
}
public virtual string FullAddress { get; set; }
public virtual IList<Office> CompanyOffices { get; set; }
}
public class Office: Identity
{
public Office()
{
Company = Company ?? new Company();
Address = Address ?? new Address();
}
public virtual Company Company { get; set; }
public virtual Address Address { get; set; }
public virtual bool IsHeadOffice { get; set; }
}
public class CompanyMapping: IdentityMapping<Company>
{
public CompanyMapping()
{
Map(x => x.Name);
HasMany(x => x.Offices).KeyColumn("CompanyId").Inverse().Cascade.AllDeleteOrphan();
}
}
public class AddressMapping: IdentityMapping<Address>
{
public AddressMapping()
{
Map(x => x.FullAddress);
HasMany(x => x.CompanyOffices).KeyColumn("AddressId").Inverse().Cascade.All();
}
}
public class OfficeMapping: IdentityMapping<Office>
{
public OfficeMapping()
{
Map(x => x.IsHeadOffice);
References(x => x.Company).Column("CompanyId").Cascade.None();
References(x => x.Address).Column("AddressId").Cascade.All();
}
}
var sessionFactory = CreateSessionFactory();
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
var companyOne = new Company { Name = "Company One" };
var companyTwo = new Company { Name = "Company Two" };
var addressOne = new Address { FullAddress = "Address One" };
var addressTwo = new Address { FullAddress = "Address Two" };
var officeOne = new Office { Company = companyOne, Address = addressOne, IsHeadOffice = true };
var officeTwo = new Office { Company = companyTwo, Address = addressTwo, IsHeadOffice = false };
var officeThr = new Office { Company = companyOne, Address = addressTwo, IsHeadOffice = true };
companyOne.AddOffice(officeOne);
companyTwo.AddOffice(officeTwo);
companyOne.AddOffice(officeThr);
session.SaveOrUpdate(companyOne);
session.SaveOrUpdate(companyTwo);
transaction.Commit();
}
}
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
var companyOne = session.Get<Company>((long)1);
session.Delete(companyOne);
transaction.Commit();
}
}
公共类OfficeMapping:IdentityMapping
{
公职申请
{
地图(x=>x.ishadoffice);
引用(x=>x.Company).Column(“CompanyId”).Cascade.None();
引用(x=>x.Address).Column(“AddressId”).Cascade.All();
}
}
测试代码:
public class Company: Identity
{
public Company()
{
Offices = Offices ?? new List<Office>();
}
public virtual string Name { get; set; }
public virtual IList<Office> Offices { get; set; }
public virtual void AddOffice(Office office)
{
office.Company = this;
Offices.Add(office);
}
}
public class Address: Identity
{
public Address()
{
CompanyOffices = CompanyOffices ?? new List<Office>();
}
public virtual string FullAddress { get; set; }
public virtual IList<Office> CompanyOffices { get; set; }
}
public class Office: Identity
{
public Office()
{
Company = Company ?? new Company();
Address = Address ?? new Address();
}
public virtual Company Company { get; set; }
public virtual Address Address { get; set; }
public virtual bool IsHeadOffice { get; set; }
}
public class CompanyMapping: IdentityMapping<Company>
{
public CompanyMapping()
{
Map(x => x.Name);
HasMany(x => x.Offices).KeyColumn("CompanyId").Inverse().Cascade.AllDeleteOrphan();
}
}
public class AddressMapping: IdentityMapping<Address>
{
public AddressMapping()
{
Map(x => x.FullAddress);
HasMany(x => x.CompanyOffices).KeyColumn("AddressId").Inverse().Cascade.All();
}
}
public class OfficeMapping: IdentityMapping<Office>
{
public OfficeMapping()
{
Map(x => x.IsHeadOffice);
References(x => x.Company).Column("CompanyId").Cascade.None();
References(x => x.Address).Column("AddressId").Cascade.All();
}
}
var sessionFactory = CreateSessionFactory();
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
var companyOne = new Company { Name = "Company One" };
var companyTwo = new Company { Name = "Company Two" };
var addressOne = new Address { FullAddress = "Address One" };
var addressTwo = new Address { FullAddress = "Address Two" };
var officeOne = new Office { Company = companyOne, Address = addressOne, IsHeadOffice = true };
var officeTwo = new Office { Company = companyTwo, Address = addressTwo, IsHeadOffice = false };
var officeThr = new Office { Company = companyOne, Address = addressTwo, IsHeadOffice = true };
companyOne.AddOffice(officeOne);
companyTwo.AddOffice(officeTwo);
companyOne.AddOffice(officeThr);
session.SaveOrUpdate(companyOne);
session.SaveOrUpdate(companyTwo);
transaction.Commit();
}
}
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
var companyOne = session.Get<Company>((long)1);
session.Delete(companyOne);
transaction.Commit();
}
}
var sessionFactory=CreateSessionFactory();
使用(var session=sessionFactory.OpenSession())
{
使用(var transaction=session.BeginTransaction())
{
var companyOne=新公司{Name=“companyOne”};
var companyTwo=新公司{Name=“companyTwo”};
var addressOne=新地址{FullAddress=“地址一”};
var addressTwo=新地址{FullAddress=“Address Two”};
var officeOne=new Office{Company=companyOne,Address=addressOne,ishadoffice=true};
var officeTwo=新办公室{Company=companyTwo,Address=addressTwo,ishadoffice=false};
var officehr=新办公室{Company=companyOne,Address=addressTwo,ishadoffice=true};
公司地址:办公室(officeOne);
公司2.地址办公室(办公室2);
公司地址办公室(人力资源办公室);
会话。保存或更新(公司名称);
会话.保存或更新(公司2);
Commit();
}
}
使用(var session=sessionFactory.OpenSession())
{
使用(var transaction=session.BeginTransaction())
{
var companyOne=session.Get((long)1);
删除(公司名称);
Commit();
}
}
代码说明:
在这里,一家公司将有多个办公室。Office是公司和地址的多对多关系,但由于可能有许多其他列(Office自己的数据),我已将关系从多对多更改为2对1对多
问题:
我希望我的应用程序删除任何在公司被删除时留下的孤立地址。但在这种情况下,当我删除我的公司时,它也会删除它的地址。但它不会检查地址是否为孤立地址。如果有另一个地址引用,它仍将被删除。根据上述测试代码,应删除“公司一号”和“地址一号”,但不删除“地址二号”,因为它不是孤立的。但它也删除了“地址二”
有谁能告诉我上面的映射有什么问题吗?我不确定NHibernate是对
删除孤儿进行全局检查,还是只对会话进行检查,真正的全局检查当然会涉及DB查询。但这实际上与此处无关,DeleteOrphan
存在的原因是当您解除实体与父实体的关联(例如,从集合中删除一个项目,然后调用父实体上的Update
),但您调用的是直接向下层叠的顶级实体上的操作
然后真正发生的事情是,您正在调用Offices
上的Delete
,根据Offices
上的映射,即All
组件,因此Offices
集合中的每个孩子都调用了Delete
,因为您在母公司公司上调用了Delete
由于Office
的映射也有一个子Address
,该子Address也映射为All
,并且Office
刚刚调用了Delete
,因此它将直接在它的Address
子对象上调用Delete
,由于直接删除
不关心其他关联(除非会话
或DB这样说),因此只需从DB中删除地址
如果您无法在此处更改实体结构,则您必须停止删除
到达未注册的地址
es(首先手动解除它们的关联),或者停止删除
级联到地址
,然后完全手动管理地址
删除
我相信如果你有灵活性的话,有一些更好的实体结构可以更好地处理这些关系:p