【问题标题】:Nhibernate class mapping and cascade propertyNhibernate 类映射和级联属性
【发布时间】:2015-11-01 18:52:14
【问题描述】:

我们有一个Address 实体,它有一个引用City 表的外键。一个Address 只引用一个City,但一个City 应该能够被许多Addresses 引用。

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. 我可以通过更新外键来更新 Address 的 City 属性吗?

到目前为止,我已经使用了Cascade 属性,并且遇到了以下问题:更新地址的城市会导致更新 City 表,或者我无法在不违反外键约束的情况下删除地址。

【问题讨论】:

    标签: c# nhibernate nhibernate-mapping cascade


    【解决方案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. 我可以通过更新外键来更新 Address 的 City 属性吗?

    与级联无关。这是标准行为,即使没有级联也可以工作,因为它会更改地址表中的值。完全没有接触城市。

    涵盖第 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();
    

    (在此处阅读更多内容Mapping-by-Code - Set and Bag

    【讨论】:

    • 谢谢!你能解释一下第二个sn-p的意义吗? m.Cascade.SaveUpdate(); 行有什么作用?
    • 很抱歉,我使用的是 fluent 版本(正如您的标签告诉我的那样),而我应该使用代码映射 - 现在已修复,希望对您有所帮助
    • 我仍然不明白第二个 sn-p 的目的 :( 当我说“2。当我删除地址时,城市没有被触及?”我的意思是说城市行仍会保留。
    • 一般来说。在多对一上进行级联是非常特殊的。因此,您的解决方案很简单(正如我所写的) - 删除该级联。仅将其保留在城市一侧。这将满足您的所有需求。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2013-01-04
    • 2010-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多