4

Я прочитал все сообщения и знаю, что IndexOutOfRange обычно происходит, потому что столбец ссылается дважды. Но я не вижу, как это происходит на основе моих сопоставлений. С SHOW_SQL true в конфиге я вижу вставку в таблицу Events, а затем IndexOutOfRangeException, которая ссылается на таблицу RadioButtonQuestions. Я не вижу, как SQL, который он пытается использовать, генерирует исключение. Я попытался использовать AutoMapping и теперь переключился на полный ClassMap для этих двух классов, чтобы попытаться сузить проблему.Fluent NHibernate - IndexOutOfRange

public class RadioButtonQuestion : Entity 
{ 
    [Required] 
    public virtual Event Event { get; protected internal set; } 

    [Required] 
    public virtual string GroupIntroText { get; set; } 
} 

public class Event : Entity 
{ 
    [Required] 
    public virtual string Title { get; set; } 

    [Required] 
    public virtual DateTime EventDate { get; set; } 

    public virtual IList<RadioButtonQuestions> RadioButtonQuestions { get; protected internal set; } 
} 




public class RadioButtonQuestionMap : ClassMap<RadioButtonQuestion> 
{ 
    public RadioButtonQuestionMap() 
    { 
     Table("RadioButtonQuestions"); 

     Id(x => x.Id).Column("RadioButtonQuestionId").GeneratedBy.Identity(); 

     Map(x => x.GroupIntroText); 
     References(x => x.Event).Not.Nullable(); 
    } 
} 


public class EventMap : ClassMap<Event> 
{ 
    public EventMap() 
    { 
     Id(x => x.Id).Column("EventId").GeneratedBy.Identity(); 
     Map(x => x.EventDate); 
     Map(x => x.Title); 
     HasMany(x => x.RadioButtonQuestions).AsList(x => x.Column("ListIndex")).KeyColumn("EventId").Not.Inverse().Cascade.AllDeleteOrphan().Not.KeyNullable(); 
    } 
} 

Сгенерированный SQL выглядит правильно:

create table Events (
    EventId INT IDENTITY NOT NULL, 
    EventDate DATETIME not null, 
    Title NVARCHAR(255) not null, 
    primary key (EventId) 
) 

create table RadioButtonQuestions (
    RadioButtonQuestionId INT IDENTITY NOT NULL, 
    GroupIntroText NVARCHAR(255) not null, 
    EventId INT not null, 
    ListIndex INT null, 
    primary key (RadioButtonQuestionId) 
) 

Это использование NH 3.3.0.4000 и FNH 1.3.0.727. Когда я пытаюсь сохранить новое событие (при подключенном RadioButtonQuestion), я вижу

NHibernate: INSERT INTO Events (EventDate, Title) VALUES (@ p0, @ p1); @ p0 = 5/21/2012 12:32 : 11 вечера [Тип: DateTime (0)], @ p1 = 'My Test Event' [Тип: String (0)] NHibernate: выберите @@ IDENTITY

Events.Tests.Events.Tasks.EventTasksTests.CanCreateEvent : NHibernate.PropertyValueException: Ошибка дегидратация значение свойства для Events.Domain.RadioButtonQuestion._Events.Domain.Event.RadioButtonQuestionsIndexBackref ----> System.IndexOutOfRangeException: SqlCeParameter с ParameterIndex '3' не содержится этой SqlCeParameterCollection.

Итак, если в столбце действительно ссылаются дважды, в чем проблема с моей конфигурацией FNH, которая вызывает это поведение? Я пытаюсь использовать отношения двунаправленного отношения (одно событие имеет много вопросов с радиокнопками) с заказом (я буду поддерживать его, поскольку NH не будет в бидиарных отношениях, из того, что я прочитал). FWIW Я также пробовал это как однонаправленное отношение, удалив Event от RadioButtonQuestion, и это все равно вызвало то же исключение.

+0

FWIW, я могу получить исключение пойти если я использую Inverse() вместо Not.Inverse(), но это кажется странным ... родитель должен управлять этим, поэтому я бы хотел Not.Inverse(), подумал я. –

+0

Первое предложение этого вопроса было ответом, который мне нужен, хорошо сформулированным, спасибо! – MrBoJangles

ответ

3

У вас есть двунаправленная связь, поэтому одна сторона должна быть отмечена как инверсная(), и это может быть только коллекция RadioButtonQuestions. Если вы хотите, чтобы коллекция была владельцем, вам нужно удалить ссылку на событие в вашем классе RadioButtonQuestion.

Кроме того, столбец EventId в таблице RadioButtonQuestions не имеет значения NULL, что может вызвать проблемы, если сопоставление коллекции не является обратным. См. note в документации.

+0

Раздражает. Я действительно хочу двунаправленную связь ... Думаю, я могу жить с Inverse(), если это правильная модель в этом случае и перечитывание документов на двунаправленную, похоже, это единственный вариант. Интересно, почему так. Guess NH действительно не хочет, чтобы вы использовали bidir ... вы также потеряли автоматическое индексирование списка. Что касается nullable, мои модульные тесты для создания и обновления проходят, но я буду следить за ними. –

6

Я использую отображение в коде (NH) 3.3.1, и я заметил, что добавление Update (ложь) и Insert (ложь) излечивает проблему:

ManyToOne(x => x.DictionaryEntity, map => 
{ 
    map.Column("Dictionary"); 
    map.Update(false); 
    map.Insert(false); 
    map.Cascade(Cascade.None); 
    map.Fetch(FetchKind.Select); 
    map.NotFound(NotFoundMode.Exception); 
    map.Lazy(LazyRelation.Proxy); 
}); 
+0

Замечательный. Это решило мою проблему. Я использовал FluentNHibernate и вам нужно было использовать: .Not.Update(). Not.Insert() ', но он все равно решил. Благодаря! –