Domanda

Ho letto tutti i post e sappi che IndexoutOFrange di solito accade perché una colonna viene referenziata due volte. Ma non vedo come sta accadendo in base alle mie mappature. Con show_sql true nella configurazione, vedo un inserto nella tabella Events e quindi un IndexOutOfRangeException che si riferisce alla tabella RadioButtonQuestions. Non riesco a vedere lo SQL che sta cercando di usare questo genera l'eccezione. Ho provato a utilizzare Automaping e ora sono passati a ClassMap pieno per queste due classi per cercare di restringere il problema.

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();
    }
}
.

L'SQL generato sembra corretto:

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)
)
.

Questo utilizza NH 3.3.0.4000 e FNH 1.3.0.727. Quando provo a salvare un nuovo evento (con una radiobuttonquestione allegata) Vedo

Norbio: inserire in eventi (EventDate, Titolo) Valori (@ P0, @ P1); @ P0= 5/21/2012 12:32:11 PM [Tipo: DateTime (0)], @ P1= 'My Test Event '[Tipo: String (0)] NHibernate: Seleziona @@ Identity

events.tests.events.tasks.eventtaskstests.cancreateevent: Nibernate.propertyvalueexception: errore di proprietà disidratante per eventi.Domain.RADIOBUTTONQUESTION._Events.Domain.event.radiobuttonquestionsindexbackref ----> System.IndexoutoFrangeexception: un SQLParameter con parametriNeterIndex '3' non è contenuto da questa SQLParameterCollection.

Quindi se una colonna viene referenziata due volte, qual è il problema con la mia configurazione FNH che causa quel comportamento? Sto cercando una relazione bidirezionale (un evento ha molte domande a pulsante radio) con ordinamento (lo manterrò da quando Nh non sarà in una relazione Bidor, da quello che ho letto). Fwiw Ho anche provato questo come una relazione unidirezionale rimuovendo il Event da RadioButtonQuestion e ha ancora causato la stessa eccezione.

È stato utile?

Soluzione

Hai un'associazione bidirezionale, quindi un lato dovrebbe essere contrassegnato come inverso () e che può essere solo la collezione RadioButtonquestions.Se vuoi che la raccolta sia il proprietario, devi rimuovere il riferimento all'evento nella classe RadioButtonquestion.

Inoltre, la colonna EventID nella tabella RADIOBUTTONQUESTIONS non è nullabile, che può causare problemi, se la mappatura della raccolta non è inversa.Vedi il Nota nella documentazione.

Altri suggerimenti

Sto usando la mappatura nel codice (NH 3.3.1) e ho notato che aggiungere aggiornamento (falso) e inserire (falso) cura il problema:

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);
});
.

Ho appena trascorso una mattutina che fa il tifo a questo errore.L'Indexoutofrangeexception mi ha mandato il percorso sbagliato inizialmente, ma ho trovato la causa. Il mio problema riguardava una mappa di classe fluentnhibernate che utilizza diversi componenti;La questione era che due proprietà sono state inaddoppiate e in modo errato mappato alla stessa colonna:

Prima:

// example is stripped for simplicity, note the column names
Component(mappedClass => mappedClass.MappedComponent1,
          map => 
          {
              map.Map(c => c.SomeProperty, "samecolumn");
          });

Component(mappedClass => mappedClass.MappedComponent2,
          map => 
          {
              map.Map(c => c.OtherProperty, "samecolumn");
          });
.

dopo:

Component(mappedClass => mappedClass.MappedComponent1,
          map => 
          {
              map.Map(c => c.SomeProperty, "firstcolumn");
          });

Component(mappedClass => mappedClass.MappedComponent2,
          map => 
          {
              map.Map(c => c.OtherProperty, "secondcolumn");
          });
.

Come si traduce in un'indexoutofrangeexception non è evidente per me;Immagino che ci sia una serie di proprietà mappate (fonte) e una serie di colonne di destinazione, e in questo caso l'array di destinazione è troppo corto per il numero di elementi nell'array delle proprietà di origine, poiché alcune delle colonne di destinazione sono identiche.

Penso che vale la pena scrivere una richiesta di tiro per il fluentennonte per verificare questa e lanciare un'eccezione più esplicita.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top