2013-05-30 3 views
2

Я пытаюсь добавить новую запись в базу данных с помощью создания нового объекта:Fluent NHibernate: Индекс находился вне диапазона исключения с отображением ReferencesAny

using (var session = conn.OpenNewSession()) 
{ 
using (var tran = session.BeginTransaction()) 
{ 
    TableHours hours = new TableHours(periodId, level, levelId.ToString(), levelTblRef); 
    hours.WorkHours = 10; 
    session.SaveOrUpdate(hours); 
    tran.Commit(); //Exception thrown here 
} 
} 

System.ArgumentOutOfRangeException брошен после transaction.Commit() : «Индекс находился вне диапазона Должно быть неотрицательным и меньше, чем размер коллекции имя параметра:.. Индекс»

ошибка, как я понимаю, происходит из-за сложного отображения:

public class TableHours 
{ 
public virtual int SaleMonthId { get; protected set; } 
public virtual int Level { get; protected set; } 
public virtual string LevelId { get; protected set; } 
public virtual Level Lvl { get; protected set; } 
public virtual decimal WorkHours { get; set; } 
//..other methods 
public TableHours(int saleMonthId, int level, string levelId, Level lvl) 
{ 
      this.SaleMonthId = saleMonthId; 
      this.Level = level; 
      this.LevelId = levelId; 
      this.Lvl = lvl; 
} 
} 

И отображение:

public class TableHoursMap : ClassMap<TableHours> 
{ 
    public TableHoursMap() 
    { 
     Table("TableHours"); 

     CompositeId() 
      .KeyProperty(x => x.SaleMonthId) 
      .KeyProperty(x => x.Level) 
      .KeyProperty(x => x.LevelId, "Id"); 

     Map(x => x.SaleMonthId); 

     Map(x => x.Level); 

     Map(x => x.LevelId, "Id"); 

     Map(x => x.WorkHours); 

     ReferencesAny(x => x.Lvl) 
      .IdentityType<string>() 
      .EntityTypeColumn("Level") 
      .EntityIdentifierColumn("Id") 
      .AddMetaValue<Level5>("5") 
      .AddMetaValue<Level4>("4") 
      .Not.Insert() 
      .Not.Update() 
      .Cascade.None() 
      .ReadOnly(); 
} 
} 

Т.е. Ссылка на поле Lvl для таблицы Level4 или Level5 в зависимости от значения уровня (4 или 5). Выбор работает отлично. Но когда я пытаюсь SaveOrUpdate, у меня есть ошибка выше.

И маленькое примечание. Без следующих атрибутов:

.Not.Insert() 
.Not.Update() 
.Cascade.None() 
.ReadOnly(); 

У меня есть указатель ошибки вне зоны действия, относящийся к полю Lvl. Вот почему я думаю, что это тот, кто виноват.

Класс Level4 и Level5 наследуется от класса Level.

Что я делаю неправильно?

+0

являются level4 и Level5 на одной и той же таблицы? – Firo

+0

Level4 и Level5 - разные таблицы. Но в зависимости от поля Level в таблице TableHours может существовать объект типа Level4 или level5. – Ksice

ответ

2

столбец Id и Level отображается в 3 раза:

  • .KeyProperty(x => x.Level) и .KeyProperty(x => x.LevelId, "Id");
  • Map(x => x.Level); и Map(x => x.LevelId, "Id");
  • ReferenceAny

я бы посоветовал удалить Map(x => x.Level); и Map(x => x.LevelId, "Id");, потому что они дублируется с помощью KeyPrope rties

Примечание:

  • .Not.Insert().Not.Update() избыточно .ReadOnly() который является ярлык для бывшего
+0

Обратите внимание, что Level и LevelId - это разные поля. И ReferenceAny - это отображение для Lvl, которое также является другим объектом, чем Level или LevelId – Ksice

+0

да, но '.KeyProperty (x => x.Level)' и 'Map (x => x.Level)' - это тот же столбец отображаемый дважды, что приводит к ошибке. Также 'TableHours.LevelId' и' TableHours.Lvl.Id' тоже одинаковы, и я бы удалил 'TableHours.LevelId', если бы знал, как сопоставить referenceAny в составном. – Firo

+0

Я удалил отображение, за исключением CompositeId и ReferenceAny, и теперь он работает! Большое спасибо! – Ksice

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