2009-09-21 3 views
3

У меня проблема с отношениями один-ко-многим. У меня есть следующие классы домена:Fluent nHibernate: отношения один-ко-многим Проблема

public class Installation : Entity<Installation> 
{   
    public virtual string Name { get; set; } 
    public virtual IList<Institution> Institutions { get; set; } 

    public Installation() 
    { 
     Institutions = new List<Institution>(); 
    } 
} 
public class Institution : Entity 
{ 
    public virtual string Name { get; set; } 
    public virtual string Address { get; set; } 
    public virtual string City { get; set; } 
    public virtual Installation Installation { get; set; }   
} 

Я сделал базовый класс сущностей в соответствии со следующим post. Я следующие отображения определены: тест

public class InstitutionMapping : ClassMap<Institution> 
{ 
    public InstitutionMapping() 
    { 
     WithTable("Institution"); 
     Id(i => i.Id).GeneratedBy.Guid(); 
     Map(i => i.Name).Not.Nullable().WithLengthOf(50); 
     Map(i => i.Address).Not.Nullable().WithLengthOf(50); 
     Map(i => i.City).Not.Nullable().WithLengthOf(50); 
     References(i => i.Installation).ColumnName("InstallationId").Not.Nullable().WithForeignKey(); 
    } 
} 

public class InstallationMapping : ClassMap<Installation> 
{ 
    public InstallationMapping() 
    { 
     WithTable("Installation"); 
     Id(i => i.Id).GeneratedBy.Guid(); 
     Map(i => i.Name).Not.Nullable().WithLengthOf(50); 
     HasMany<Institution>(i => i.Institutions).KeyColumnNames.Add("InstallationId").Inverse().Cascade.All(); 
    } 
} 

I блок добавление учреждений к установке следующим образом:

Installation installation = TestHelper.CreateAnonymousInstallation(); 
installation.Institutions.Add(TestHelper.CreateAnonymousInstitution()); 
installation.Institutions.Add(TestHelper.CreateAnonymousInstitution()); 
session.Save(installation);  
session.Flush(); 
session.Clear(); 
Installation returnedInstallation = session.Get<Installation>(installation.Id); 
Assert.AreEqual(2, returnedInstallation.Institutions.Count); 

я получаю исключение утверждения, поскольку возвращено число учреждений, равно 0. У меня есть проверяется в SQL Profiler, и учреждения сохраняются в базе данных, но их InstallationId имеет значение null. Может ли кто-нибудь сказать мне, что я делаю неправильно?

+0

http://stackoverflow.com/questions/713637/inverse-attribute-in-nhibernate –

ответ

5

Если у вас есть постоянный сбор с inverse="false", то родительским объект имеет отношение и любые изменения в коллекцию родителя будет отражаются в базе данных.

Когда у вас есть постоянная коллекция с inverse="true", тогда дочерний объект владеет этим отношением, и любые изменения ссылки на родителя будут отражены в базе данных.

Поскольку вы установили inverse="true", вам необходимо будет изменить ссылку дочернего объекта на родительский объект, чтобы NHibernate мог его забрать. Если вы хотите, чтобы NHibernate забирал изменения в отношениях, когда вы добавляете детей или удаляете детей из коллекции родителя, вы должны установить inverse="false" в коллекции.

+0

Действительно, он решает мою проблему, когда нет Not.Nullable() и когда PatronId может быть нулевым. Если это не так, когда я сохраняю установку в своем модульном тесте, я получаю следующую ошибку: «NHibernate.PropertyValueException: свойство not-null ссылается на значение null или переходное значение». Как преодолеть эту проблему? – GUZ

+0

Ответ: вы всегда должны изменять обе стороны отношений. Установите родительскую ссылку для ребенка и каждый раз добавляйте ее в коллекцию родителя. Независимо от того, делаете ли вы это в два шага каждый раз или создаете ли вы какой-то прозрачный способ сделать это за один шаг, зависит от вас. – yfeldblum

+0

Я понимаю. У меня есть еще одна проблема: я тестирую устройство, используя PersistenceSpecification. При проверке сопоставления метода Instinct CheckList также вызывается NHibernate.PropertyValueException: свойство not-null ссылается на значение null или переходное значение. Как использовать PersistenceSpecification, когда мне нужно изменить обе стороны отношений? – GUZ

1

Вы должны вручную установить установки свойства института, в частности,

Installation installation = TestHelper.CreateAnonymousInstallation(); 
Institution institution = TestHelper.CreateAnonymousInstitution(); 
institution.Installation = installation; 
installation.Institutions.Add(institution); 
+0

Помните, что nh не автосинхронизирует двунаправленные отношения. – epitka

+0

Я знаю, что ваше решение работает. Однако я думал, что в случае нормальных двунаправленных отношений NHibernate должен делать это автоматически. Есть ли способ настроить решение, так что нужно только добавить детей в коллекцию без установки родительской ссылки? – GUZ

+0

Да. Не устанавливайте 'inverse =" true "'. Но тогда, если вы установите ссылку на родителя для своего родителя напрямую, а не добавляете ребенка в коллекцию родителя, NHibernate может не изменять отношение. – yfeldblum

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