Nhibernate类映射和级联属性



我们有一个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);
            });
    }
}

我应该如何更改类映射,以便:

  1. 当我删除一个城市时,该城市的所有地址都会被删除吗
  2. 当我删除地址时,城市没有被触摸
  3. 我可以通过更新外键来更新地址的城市属性吗

到目前为止,我已经使用了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点:

  1. 我可以通过更新外键来更新地址的城市属性吗

不是级联。这是标准行为,即使没有级联也能工作,因为它会更改Address表中的值。一点也不接触这座城市。

涵盖第2点:

  1. 当我删除地址时,城市没有被触摸

好吧,我们应该完全消除级联,因为。。。在这个方向上不需要它。但是,此设置将适用于点2

this.ManyToOne(
    e => e.City,
    m =>
    {
        m.Column("id_city");
        m.Cascade(Cascade.Persist);

覆盖第一点:

  1. 当我删除一个城市时,该城市的所有地址都会被删除吗

我们必须做很多事情。我们需要扩展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();

(点击此处阅读更多按代码映射-集和袋)

最新更新