【问题标题】:Fluent NHibernate one-to-many relationship setting foreign key to nullFluent NHibernate 一对多关系将外键设置为空
【发布时间】:2012-06-28 02:55:05
【问题描述】:

我有一个带有两个相关类的简单 Fluent NHibernate 模型:

public class Applicant
    {
        public Applicant()
        {
            Tags = new List<Tag>();
        }

        public virtual int Id { get; set; }

        //other fields removed for sake of example

        public virtual IList<Tag> Tags { get; protected set; }

        public virtual void AddTag(Tag tag)
        {
            tag.Applicant = this;
            Tags.Add(tag);
        }
    }


public class Tag
{
    public virtual int Id { get; protected set; }
    public virtual string TagName { get; set; }

    public virtual Applicant Applicant { get; set; }
}

我的流畅映射如下:

public class ApplicantMap : ClassMap<Applicant>
    {
        public ApplicantMap()
        {
            Id(x => x.Id);

            HasMany(x => x.Tags).Cascade.All();
        }
    }

    public class TagMap : ClassMap<Tag>
    {
        public TagMap()
        {
            Id(x => x.Id);
            Map(x => x.TagName);

            References(x => x.Applicant).Not.Nullable();
        }
    }

每当我尝试更新申请人(插入新的工作正常)时,它都会失败,并且我在日志中看到以下 SQL 异常:

11:50:52.695 [6] DEBUG NHibernate.SQL - UPDATE [Tag] SET Applicant_id = null WHERE Applicant_id = @p0;@p0 = 37 [Type: Int32 (0)] 
11:50:52.699 [6] ERROR NHibernate.AdoNet.AbstractBatcher - Could not execute command: UPDATE [Tag] SET Applicant_id = null WHERE Applicant_id = @p0 System.Data.SqlClient.SqlException (0x80131904): Cannot insert the value NULL into column 'Applicant_id', table 'RecruitmentApp.dbo.Tag'; column does not allow nulls. UPDATE fails.

为什么 NHibernate 试图更新标签表并将申请人 ID 设置为空?我在这方面不知所措。

【问题讨论】:

    标签: nhibernate fluent-nhibernate fluent-nhibernate-mapping


    【解决方案1】:

    Applicant.Tags 设置为Inverse 将指示NHibernate 在Applicant 之后保存Tags

    public class ApplicantMap : ClassMap<Applicant>
    {
        public ApplicantMap()
        {
            Id(x => x.Id);
    
            HasMany(x => x.Tags).Cascade.All().Inverse();
        }
    }
    

    更多细节:

    Inverse(相对于.Not.Inverse())表示关系的另一方(在这种情况下,每个Tag)负责维护关系。因此,NHibernate 知道必须首先保存Applicant,以便Tag 对其Applicant 具有有效的外键。

    经验法则:包含外键的实体通常是所有者,所以另一个表应该有Inverse

    【讨论】:

    • 工作就像一个魅力。谢谢!我仍然对 inverse 的含义有些困惑,但我会做一点阅读。我在文档中没有看到它。
    • 非常感谢您解决了它没有任何问题的问题。
    • 这对我来说很奇怪。为什么标签是所有者?这些标签与特定的申请人相关联。您创建一个申请人,然后为其添加标签。您不创建标签,并将它们与申请人相关联?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    • 2011-04-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多