Я пытаюсь заставить 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
, как эта статья рекомендует).