Вопрос по nhibernate, fluent-nhibernate-mapping, fluent-nhibernate – Свободное отношение «один ко многим» NHibernate, устанавливающее внешний ключ на ноль

5

У меня есть простая модель 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();
        }
    }

Всякий раз, когда я пытаюсьupdate заявитель (вставка нового работает нормально), он терпит неудачу, и я вижу следующее исключение 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 пытается обновить таблицу тегов и установить Applicant_id на ноль? Я в растерянности по этому поводу.

Ваш Ответ

1   ответ
13

Applicant.Tags вInverse поучат NHibernate сохранитьTags послеApplicant.

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

Большое спасибо за решение проблемы, она работала без проблем.
Работал как шарм. Спасибо! Я все еще немного запутался в том, что означает обратное, но я немного прочту. Я не вижу этого в документации, хотя. arknotts
Это странно для меня. Почему тег является владельцем? Теги привязаны к конкретному заявителю. Вы создаете кандидата, а затем добавляете к нему теги. Вы не создаете теги и не связываете их с заявителем?

Похожие вопросы