查看实体 -
class Person
{
int id { get; set; };
IList<PersonAddress> Addresses { set; get; }
...
}
现在,当我从地址列表中删除一些地址时,从UI更新人员 然后我想从db中删除地址记录。目前,这是更新地址表设置 personId = NULL 而不是删除地址记录。有谁知道如何做到这一点。可能是一些映射问题。
这里我要添加整个Person
类映射文件。
public class PersonMappingOverride : IAutoMappingOverride<Person>
{
public void Override(AutoMapping<Person> mapping)
{
mapping.Schema(Schemas.Common);
mapping.Table("Person");
mapping.Map(x => x.FirstName).Not.Nullable();
mapping.Map(x => x.LastName).Not.Nullable();
mapping.Map(x => x.DateOfBirth).Nullable();
mapping.References(x => x.Title);
mapping.References(x => x.Ethnicity);
mapping.References(x => x.Language);
mapping.References(x => x.Religion);
mapping.References(x => x.Country);
mapping.References(x => x.Gender).Not.Nullable();
mapping.References(x => x.LoginDetail);
mapping.HasMany(x => x.Addresses)
.ForeignKeyConstraintName("FK_PersonAddress_Person_PersonID")
.Where("DeletedDate is null")
.Cascade.AllDeleteOrphan()
.Cascade.SaveUpdate();
mapping.HasMany(x => x.TelephoneNumbers)
.ForeignKeyConstraintName("FK_PersonTelephoneNumber_Person_PersonID")
.Where("DeletedDate is null")
.Cascade.AllDeleteOrphan()
.Cascade.SaveUpdate();
mapping.HasMany(x => x.EmailAddresses)
.ForeignKeyConstraintName("FK_PersonEmailAddress_Person_PersonID")
.Where("DeletedDate is null")
.Cascade.AllDeleteOrphan()
.Cascade.SaveUpdate();
mapping.References(x => x.Photograph);
mapping.References(x => x.Signature);
mapping.HasMany(x => x.Photographs)
.ForeignKeyConstraintName("FK_PersonPhotograph_Person_PersonID")
.Where("DeletedDate is null")
.Cascade.AllDeleteOrphan()
.Cascade.SaveUpdate();
mapping.HasMany(x => x.Signatures)
.ForeignKeyConstraintName("FK_PersonSignature_Person_PersonID")
.Where("DeletedDate is null")
.Cascade.AllDeleteOrphan()
.Cascade.SaveUpdate();
//mapping.HasMany(x => x.JobRoles)
// .ForeignKeyConstraintName("FK_PersonJobRole_Person_PersonID");
mapping.HasMany(x => x.Skills)
.ForeignKeyConstraintName("FK_PersonSkill_Person");
mapping.HasMany(x => x.SpokenLanguages)
.ForeignKeyConstraintName("FK_PersonSpokenLanguage_Person");
mapping.HasMany(x => x.ForbiddenCentres)
.ForeignKeyConstraintName("FK_PersonForbiddenCentre_Person");
mapping.HasMany(x => x.Availabilities)
.ForeignKeyConstraintName("FK_PersonAvailability_Person");
mapping.HasMany(x => x.Qualifications)
.ForeignKeyConstraintName("FK_PersonQualification_Person");
mapping.IgnoreProperty(x => x.PrimaryEmailAddress);
mapping.IgnoreProperty(x => x.WorkAddress);
}
}
这适用于PersonAddress
映射:
public class PersonAddressMappingOverride : IAutoMappingOverride<PersonAddress>
{
public void Override(AutoMapping<PersonAddress> mapping)
{
mapping.Schema(Schemas.Common);
mapping.Table("PersonAddress");
mapping.References(x => x.Person);
mapping.References(x => x.Address).Cascade.SaveUpdate().Not.Nullable();
mapping.References(x => x.AddressType).Not.Nullable();
}
}
答案 0 :(得分:2)
编辑:添加了流利的映射,附加在
之后假设您使用<bag>
的映射如下所示:
<bag name="address" >
<key column="PersonId" />
<one-to-many class="Address"/>
</bag>
这是有效的,并指示NHibernate维护address
集合。如果将新对象添加到集合中,则会更新其PersonId
列与当前Person的关系。如果删除了某个地址,则其PersonId
列将设置为空。
如果我们想要更多,我们可以使用级联:
<bag name="address" cascade="all-delete-orphan"
<key column="PersonId" />
<one-to-many class="Address"/>
</bag>
在这种情况下,我们不仅关心关系,甚至关心集合中的项目。检查此映射以获取更多详细信息:6.2. Mapping a Collection(小提取):
(6)cascade(可选 - 默认为none)启用级联到子实体的操作
现在,当我们从集合中删除地址实例时,它也将从持久性中删除。但是,这样做的步骤将是:
PersonId
设置为NULL 为避免这种情况,我们可以添加另一个映射功能:逆映射。因此,如果该地址已映射到Person(多对一),我们可以使用此映射(请参阅inverse="true"
):
<bag name="address" cascade="all-delete-orphan" inverse="true">
<key column="PersonId" />
<one-to-many class="Address"/>
</bag>
可以将其标记为最有效,因为所有更改都将直接在地址元素上执行(无中间步骤)
注意:只需从6.2开始:
注意:用inverse =“false”映射的大型NHibernate包效率低,应该避免; NHibernate无法单独创建,删除或更新行,因为没有可用于标识单个行的键。
编辑:流畅的映射
根据您在问题中包含的映射,您应该以这种方式调整地址映射:
...
mapping.HasMany(x => x.Addresses)
.ForeignKeyConstraintName("FK_PersonAddress_Person_PersonID")
.Where("DeletedDate is null")
.Inverse() // this will cause the direct DELETE to be issued
.Cascade.AllDeleteOrphan() // this is the only Cascade which should be used
;