Nhibernate类映射和级联属性

时间:2015-11-01 18:52:14

标签: c# nhibernate nhibernate-mapping cascade

我们有一个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. 我可以通过更新外键来更新地址的城市属性吗?
  4. 到目前为止,我已经使用了Cascade属性,并且遇到了地址城市更新导致城市表更新的问题,或者我没有在不违反外键约束的情况下删除地址

1 个答案:

答案 0 :(得分:1)

上面显示的many-to-one部分(此处也讨论NHibernate Many-to-one cascade可以设置为这些值

// 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() 

(在此处阅读Mapping-by-Code - ManyToOne

这将涵盖点数......以上都不是。因为没有要求是要求从地址到城市的级联。

第3点:

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

不是关于级联的。这是标准的behviour,即使没有级联也可以工作,因为它会更改Address表中的值。根本没有触及城市。

涵盖第2点:

  
      
  1. 当我删除地址时,城市未被触及?
  2.   

好吧,我们应该删除级联,因为......在这个方向上不需要它。但是,此设置适合第2点

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

要涵盖第一点:

  
      
  1. 当我删除城市时,该城市的所有地址都将被删除?
  2.   

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

(在此处阅读Mapping-by-Code - Set and Bag