nHibernate ManyToManyToMany с помощью Fluent

У меня есть структура здесь, у меня есть отношение ManyToManyToMany.

Это мои (усеченные) беглые отображения.

public AgencyMap() 
{
    Id(x => x.AgencyId, "AgencyId");            
    Map(x => x.AgencyCode, "AgencyCode");
    HasManyToMany<Personnel>(x => x.Personnel)
    .WithTableName("AgencyPersonnel")
    .WithParentKeyColumn("AgencyId")
        .WithChildKeyColumn("PersonnelId").Cascade.All().LazyLoad();
}

public PersonnelMap() 
{
    Id(x => x.PersonnelId, "PersonnelId");    
    HasManyToMany<Discipline>(x => x.Disciplines)
        .WithTableName("AgencyPersonnelDiscipline")
        .WithParentKeyColumn("AgencyPersonnelId")
        .WithChildKeyColumn("DisciplineId")
        .Cascade.SaveUpdate().LazyLoad();
}           

public DisciplineMap() 
{
    SchemaIs("dbo");            
    Id(x => x.DisciplineId, "DisciplineId");            
    Map(x => x.DisciplineCode, "DisciplineCode");           
    Map(x => x.Description, "Description");         
}   

Если я затем запускаю такой код.

Agency agency = m_AgencyRepository.Get(10);
var personnel = new Personnel() { ... };
personnel.Disciplines.Add(new Discipline() { ... });
agency.Personnel.Add(personnel);
m_AgencyRepository.Save(agency);

Когда я запускаю этот код, я получаю эту ошибку.

could not insert collection: [PPSS.Model.Personnel.Disciplines#22][SQL: SQL not available]
The INSERT statement conflicted with the FOREIGN KEY constraint "AgencyPersonnel_AgencyPersonnelDiscipline_FK1". The conflict occurred in database "PPSS2", table "dbo.AgencyPersonnel", column 'AgencyPersonnelId'.\r\nThe statement has been terminated.

Сущности выглядят так.

public class Agency
{
  public virtual int AgencyId {get; set;}
  public virtual IList<Personnel> Personnel {get; set;}
}

public class Personnel
{
  public virtual int PersonnelId {get; set;}
  public virtual IList<Agency> Agencies {get; set;}
  public virtual IList<Dependency> Dependencies {get; set;}
}

public class Dependency
{
  public virtual int DependencyId {get; set;}
  public virtual string Name {get; set;}
}

Если я добавлю инверсию к ManyToMany в персонале, тогда персонал будет сохранен, но не дисциплины (исключения не возникнут).

Как это отображение должно быть сделано?

Редактировать:

У меня есть еще информация. Если я отключу ограничение AgencyPersonnel_AgencyPersonnelDiscipline_FK1, тогда все будет вставлено нормально. Это заставляет меня думать, что проблема в том порядке, который вставляет nHibernate. Я ожидаю, что это будет сделано по порядку.

  1. ВСТАВИТЬ В Персонал
  2. Получить последний ключ (PersonnelId)
  3. INSERT INTO AgencyPersonnelDiscipline с AgencyId и PersonnelId.

Это не будет нарушать никаких ограничений.


person Craig    schedule 14.05.2009    source источник
comment
Как выглядят ваши классы сущностей?   -  person Paco    schedule 15.05.2009
comment
Я добавил классы сущностей   -  person Craig    schedule 15.05.2009


Ответы (2)


Поскольку это усеченное отображение, я сделаю снимок в темноте :). Такое исключение обычно происходит со мной, когда у меня есть 2 объекта: X и Y, и я сопоставляю их с обоих направлений, например:

X имеет свойство Y

Y имеет список X

И ни у одного из них не установлен атрибут Inverse(). Проверьте, сопоставляете ли вы что-то в обоих направлениях, но не устанавливаете ли для них Inverse().

person sirrocco    schedule 20.05.2009

Учитывая, что карты, которые у вас есть, верны для типов, которые вы указали, вы не сопоставили обратно от Персонала к Агентству или от Дисциплины к Персоналу.

person pms1969    schedule 26.02.2010