2015-03-08 5 views
2

Как настроить сопоставления для двунаправленного сопоставления в сценарии X-ссылки Y, Y имеет много Xs, так что когда я добавляю много Xs в Y экземпляр и сохранить экземпляр Y, он будет работать правильно?(Свободно) NHibernate: HasMany/Ссылки (двунаправленный) + Каскад Сохранить

сделать эту проблему ясно, вот код:

ClientCompany модель имеет HasManyContactPerson связанные модели:

public class ClientCompany 
{ 
    // .... 
    public virtual ISet<ContactPerson> ContactPeople { get; set; } 
} 

// mapping: 
HasMany(x => x.ContactPeople) 
      .AsSet() 
      .Inverse() 
      .Cascade.All(); 

ContactPerson не имеет-обнуляемого "ClientCompany" поле реферирование материнская компания:

public class ContactPerson 
{ 
    // .... 
    public virtual ClientCompany ClientCompany { get; set; } 
} 

References(x => x.ClientCompany).Not.Nullable(); 

вызов этого кода:

sess.Save(new ClientCompany() 
      {      
       ContactPeople = new HashSet<ContactPerson>() 
       { 
        new ContactPerson() 
       } 
      }); 

причина это исключение:

не-нулевые ссылки собственности нулевое или транзиторное значение xxxx.ContactPerson.ClientCompany

это просто упростило случай, я использую AutoMapper в моем реальном проекте, поэтому установка ссылки вручную is не решение

ответ

3

Самым важным thinkg в ОРМ мире, а именно при использовании NHibernate, является:

ВСЕГДА установить обе стороны отношения.

Это действительно способ, как установить обе стороны:

var person = new ContactPerson(); 
var company = new ClientCompany 
{      
    ContactPeople = new HashSet<ContactPerson>() 
    { 
     person, 
    }, 
}; 
person.ClientCompany = company 

sess.Save(company); 

По картографирования является Person объявлен ответственным за его связи (обратного отображения .Inverse()).

А это означает, что он должен установить отношение к его родительскому элементу. Это отношение используется позже для инструкции INSERT ... и оно не может быть нулевым.

Не нужно спасать компанию и человека отдельно. только важное и совершенно важное предмет необходимо установить обе ссылки боковые. Это ДОЛЖНО.

Не уверен, что вы можете сделать с автоматическим картографа ... но какой-то оберточной/экранированием двунаправленной настройки может быть какой-то особый метод на объекте POCO:

public class ClientCompany 
{ 
    // .... 
    public virtual ISet<ContactPerson> ContactPeople { get; set; } 
    public virtual AddPerson(ContactPerson person) 
    { 
     ContactPeople = ContactPeople ?? new HashSet<ContactPerson>(); 
     ContactPeople.Add(person); 
     person.ClientCompany = this; 
    } 
} 

Теперь мы просто для звонка AddPerson() в нужное время ...

+0

Спасибо!Я думал, что могу как-то позволить этому «авто» установить ссылку, когда «Сохранить» вызывается в объекте «компания». Таким образом, можно было бы позволить AutoMapper делать магию. –

+0

Ссылка должна быть задана явно. Это действительно важно. Если вы это сделаете, остальное будет обработано NHibernate ... Еще один способ пойти * (но я не уверен, что ваш авто-картограф способен) * заключается в создании специального метода ** 'AddPerson()' ** и реализуйте там двунаправленную настройку * (от родителя к ребенку, от ребенка к родительскому) * ... Но тогда AutoMapper должен иметь возможность вызвать такой метод 'AddPerson()' –

Смежные вопросы