Двунаправленная ассоциация NHibernate - PullRequest
0 голосов
/ 28 марта 2012

Я пытаюсь смоделировать родительскую / дочернюю ассоциацию, где родительскому классу (Person) принадлежит много экземпляров дочернего класса (OwnedThing) - я хочу, чтобы экземпляры OwnedThing сохранялись автоматически при сохранении класса Person, и я хочу, чтобы ассоциация должна быть двунаправленной.

public class Person
{
        public class MAP_Person : ClassMap<Person>
        {
                public MAP_Person()
                {
                        this.Table("People");
                        this.Id(x => x.ID).GeneratedBy.GuidComb().Access.BackingField();
                        this.Map(x => x.FirstName);
                        this.HasMany(x => x.OwnedThings).Cascade.AllDeleteOrphan().KeyColumn("OwnerID").Inverse();
                }
        }

        public virtual Guid ID { get; private set; }
        public virtual string FirstName { get; set; }
        public virtual IList<OwnedThing> OwnedThings { get; set; }

        public Person()
        {
                OwnedThings = new List<OwnedThing>();
        }
}



public class OwnedThing
{
        public class MAP_OwnedThing : ClassMap<OwnedThing>
        {
                public MAP_OwnedThing()
                {
                        this.Table("OwnedThings");
                        this.Id(x => x.ID).GeneratedBy.GuidComb().Access.BackingField();
                        this.Map(x => x.Name);
                        this.References(x => x.Owner).Column("OwnerID").Access.BackingField();
                }
        }

        public virtual Guid ID { get; private set; }
        public virtual Person Owner { get; private set; }
        public virtual string Name { get; set; }
}

Если я установлю Person.OwnedThings на Inverse, то экземпляры OwnedThing не сохраняются при сохранении Person. Если я не добавлю Inverse, то сохранение будет успешным, но person.OwnedThings [0] .Owner всегда будет нулевым после того, как я получу его из БД.

UPDATE При сохранении данных NHibernate установит один конец ассоциации в базе данных, потому что он устанавливается через многолинейный конец ассоциации, поэтому, когда я получаю OwnedThing из БД, он имеет ссылку на Человек установлен. Моя нулевая ссылка была от Энверса, который, кажется, не делает то же самое.

Ответы [ 2 ]

0 голосов
/ 31 июля 2012

Правильно ли я вас понимаю, что ваша проблема возникает только с "историческими" сущностями, прочитанными nhibernate envers?

Если это так, это может быть вызвано этой ошибкой https://nhibernate.jira.com/browse/NHE-64 Обходной путь на данный момент заключается в использовании Merge вместо (SaveOr) Update.

0 голосов
/ 28 марта 2012

OwnedThings[0].Owner, скорее всего, равно нулю, потому что вы не устанавливаете его при добавлении.При использовании двунаправленных отношений вы должны сделать что-то вроде следующего:

Person person = new Person();
OwnedThing pwnedThing = new OwnedThing();

pwnedThing.Owner = person;
person.OwnedThings.Add(pwnedThing);

Если вы не расширили, установите pwnedThing.Owner, и вы запросите тот же объект в том же ISession, который вы создали для негобудет нулевымОбычно у меня есть методы добавления или удаления, которые выполняют эту «дополнительную» работу для меня.Возьмите следующий пример:

public class Order : Entity
{
    private IList<OrderLine> orderLines;
    public virtual IEnumerable<OrderLine> OrderLines { get { return orderLines.Select(x => x); } }

    public virtual void AddLine(OrderLine orderLine)
    {
        orderLine.Order = this;
        this.orderLines.Add(orderLine);
    }

    public virtual void RemoveLine(OrderLine orderLine)
    {
        this.orderLines.Remove(orderLine);
    }
}

public class OrderMap : ClassMap<Order>
{
    public OrderMap()
    {
        DynamicUpdate();
        Table("ORDER_HEADER");
        Id(x => x.Id, "ORDER_ID");

        HasMany(x => x.OrderLines)
            .Access.CamelCaseField()
            .KeyColumn("ORDER_ID")
            .Inverse()
            .Cascade.AllDeleteOrphan();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...