我们有一个Address
实体,它有一个引用City
表的外键。Address
只引用一个City
,但City
应该能够被许多Address
引用。
public class Address : Entity
{
public virtual string AddressLine1 { get; set; }
public virtual string AddressLine2 { get; set; }
public virtual City City { get; set; }
}
public class City : Entity
{
public virtual string CityName { get; set; }
}
这是Address
类映射。
public class AddressClassMapping : ClassMapping<Address>
{
public AddressClassMapping()
{
this.Schema("dbo");
this.Table("addresses");
this.Cache(e => e.Usage(CacheUsage.ReadWrite));
this.Id(e => e.Id,
m => { m.Column("id_address"); m.Generator(Generators.Native);});
this.Property(e => e.AddressLine1,
m => { m.Column("address_line_1"); m.NotNullable(true); });
this.Property(e => e.AddressLine2,
m => { .Column("address_line_2");
m.NotNullable(true); });
this.ManyToOne(
e => e.City,
m =>
{
m.Column("id_city");
m.Cascade(Cascade.All);
});
}
}
我应该如何更改类映射,以便:
- 当我删除一个城市时,该城市的所有地址都会被删除吗
- 当我删除地址时,城市没有被触摸
- 我可以通过更新外键来更新地址的城市属性吗
到目前为止,我已经使用了Cascade
属性,并遇到了以下问题:对地址所在城市的更新会导致对城市表的更新,或者我无法在不违反外键约束的情况下删除地址。
上面显示的many-to-one
部分(此处也讨论了NHibernate多对一级联)可以设置为这些值
// xml
cascade="all|none|save-update|delete"
// maping by code
Cascade.All | Cascade.None | Cascade.Persist | Cascade.Remove
// fluent
Cascade.All() | Cascade.SaveUpdate() | Cascade.None() | Cascade.Delete()
(阅读更多此处按代码映射-ManyToOne)
这将涵盖点号。。。好吧,以上都没有。因为没有任何要求要求从地址级联到城市。
第3点:
- 我可以通过更新外键来更新地址的城市属性吗
不是级联。这是标准行为,即使没有级联也能工作,因为它会更改Address表中的值。一点也不接触这座城市。
涵盖第2点:
- 当我删除地址时,城市没有被触摸
好吧,我们应该完全消除级联,因为。。。在这个方向上不需要它。但是,此设置将适用于点2
this.ManyToOne(
e => e.City,
m =>
{
m.Column("id_city");
m.Cascade(Cascade.Persist);
覆盖第一点:
- 当我删除一个城市时,该城市的所有地址都会被删除吗
我们必须做很多事情。我们需要扩展POCO关系,并引入一对多映射。这将满足需要:
public class City : Entity
{
public virtual IList<Address> Addresses { get; set; }
}
映射
按代码映射:
Set(x => x.Addresses, c =>
{
...
c.Cascade(Cascade.All.Include(Cascade.DeleteOrphans));
流畅版
HasMany(x => x.Addresses)
...
Cascade.AllDeleteOrphan();
(点击此处阅读更多按代码映射-集和袋)