Понимание внешнего ключа not-null = true и обратного поведения в отношении нуль-к-одному с NHibernate

Я пытаюсь заставить NHibernate использовать многие стороны коллекции для управления двунаправленной ассоциацией для моделирования отношения ноль к единице.

Родительский класс и карта:

public class Parent
{
    private ICollection children;
    public Parent()
    {
        this.children = new HashedSet();
    }
    public virtual Guid Id { get; protected internal set; }
    public virtual Child Child
    {
        get { return children.FirstOrDefault(); }
        set
        {
            {
                this.children.Clear();
                if (value != null)
                {
                    this.children.Add(value);
                }
            }
        }
    }
}

public class ParentMap : ClassMap
{
    public ParentMap()
    {
        this.Id(x => x.Id)
            .GeneratedBy.GuidComb();
        this.HasMany(Reveal.Member("children"))
            .Access.Field()
            .Cascade.All()
            .Not.Inverse()
            .AsSet();
    }
}

Дочерний Класс и карта:

public class Child
{
    public virtual Guid Id { get; protected internal set; }
    public virtual Parent Parent { get; set; }
}

public class ChildMap : ClassMap
{
    public ChildMap()
    {
        this.Id(x => x.Id)
            .GeneratedBy.GuidComb();
        this.References(x => x.Parent)
            .Not.Nullable()
            .Cascade.All();
    }
}

Следующий код производит две вставки и обновление:

var parent = new Parent();
var child = new Child();
parent.Child = child;
child.Parent = parent;
session.Save(parent);
session.Flush();

Обратите внимание на по существу дублированный SQL для второй вставки и следующее обновление:

exec sp_executesql N'INSERT INTO [Parent] (Id) VALUES (@p0)',N'@p0 uniqueidentifier',@p0='AA5A146E-E3F5-4373-B7A8-9EF301171401'
go
exec sp_executesql N'INSERT INTO [Child] (Parent_id, Id) VALUES (@p0, @p1)',N'@p0 uniqueidentifier,@p1 uniqueidentifier',@p0='AA5A146E-E3F5-4373-B7A8-9EF301171401',@p1='B78C4461-A217-47FC-BE02-9EF30117140A'
go
exec sp_executesql N'UPDATE [Child] SET Parent_id = @p0 WHERE Id = @p1',N'@p0 uniqueidentifier,@p1 uniqueidentifier',@p0='AA5A146E-E3F5-4373-B7A8-9EF301171401',@p1='B78C4461-A217-47FC-BE02-9EF30117140A'
go

Хотя этот код создает печально известное свойство not-null ссылается на нулевое или переходное значение, обратное :

var parent = new Parent();
var child = new Child();
parent.Child = child;
//child.Parent = parent;
session.Save(parent);
session.Flush();

Я нашел множество сообщений по этому поводу, но еще не нашел подробного руководства о том, как сделать ноль к единице, с inverse = false на стороне один .

Я пробовал метод «один-ко-многим» / «один-к-одному», упомянутый здесь .

Также я ' Мы обнаружили в NHibernate несколько открытых проблем, касающихся (не) обнуляемых внешних ключей: NH-941 , NH-1050 и т. д.

Что я делаю не так?

Edit 2011-05-30

Итак, мое временное решение состоит в том, чтобы использовать стандартную настройку inverse = true для многих сторон и совершить некоторую магию в установщике родительского элемента:

public virtual Child Child
{
    get { return children.FirstOrDefault(); }
    set
    {
        {
            this.children.Clear();
            if (value != null)
            {
                value.Parent = this;
                this.children.Add(value);
            }
        }
    }
}

Но Меня все еще сбивает с толку поведение inverse = false , которое должно быть эквивалентом inverse = true на стороне «многие к одному» (интересно, что FluentNhibernate не позволяет ManyToOnePart, чтобы установить inverse = true , как эта статья рекомендует).

11
задан Frédéric 2 May 2017 в 18:09
поделиться