Frage

Ich habe alle Beiträge gelesen und weiß, dass IndexOutOfRange normalerweise auftritt, weil auf eine Spalte zweimal verwiesen wird.Aber ich sehe aufgrund meiner Zuordnungen nicht, wie das passiert.Mit SHOW_SQL true in der Konfiguration sehe ich eine Einfügung in die Events tisch und dann ein IndexOutOfRangeException das bezieht sich auf die RadioButtonQuestions Tabelle.Ich kann das SQL, das es zu verwenden versucht, das die Ausnahme generiert, nicht sehen.Ich habe versucht, AutoMapping zu verwenden und bin jetzt auf voll umgestiegen ClassMap für diese beiden Klassen, um zu versuchen, das Problem einzugrenzen.

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

Das generierte SQL sieht korrekt aus:

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

Dies verwendet NH 3.3.0.4000 und FNH 1.3.0.727.Wenn ich versuche, ein neues Ereignis zu speichern (mit einer angehängten RadioButtonQuestion), sehe ich

NHibernate:WERTE IN Ereignisse (Ereignisdatum, Titel) EINFÜGEN (@ p0, @ p1); @ p0 = 21.5.2012 12: 32:11 Uhr [Typ:Datum / Uhrzeit (0)], @p1 = 'Mein Testereignis' [Typ:Zeichenfolge (0)] NHibernate:@@IDENTITÄT auswählen

Anl.Test.Anl.Aufgaben.Ereignisaufgabentests.Ereignis erstellen:NHibernate.PropertyValueException :Fehler beim Dehydratisieren des Eigenschaftswerts für Ereignisse.Domain.Radiobuttonfrage._Anl.Domain.Veranstaltung.RADIOBUTTONFRAGENINDEXZURÜCKREF ----> System.IndexOutOfRangeException :Ein SqlCeParameter mit dem ParameterIndex '3' ist in dieser SqlCeParameterCollection nicht enthalten.

Wenn also wirklich zweimal auf eine Spalte verwiesen wird, was ist das Problem mit meiner FNH-Konfiguration, das dieses Verhalten verursacht?Ich versuche eine Bidirektionsbeziehung (ein Ereignis hat viele Optionsfeldfragen) mit der Bestellung (ich werde sie beibehalten, da NH nach dem, was ich gelesen habe, keine Bidir-Beziehung hat).FWIW, ich habe dies auch als unidirektionale Beziehung versucht, indem ich das entfernt habe Event von RadioButtonQuestion und es verursachte immer noch die gleiche Ausnahme.

War es hilfreich?

Lösung

Sie haben eine bidirektionale Zuordnung, daher sollte eine Seite als Inverse () markiert sein und das kann nur die RadioButtonQuestions Sammlung sein.Wenn Sie möchten, dass die Sammlung der Eigentümer ist, müssen Sie den Verweis auf das Ereignis in Ihrer RadioButtonQuestion Klasse entfernen.

Außerdem ist die EventID-Spalte in der Tabelle RadioButtonQuestions nicht nullfähig, was zu Problemen führen kann, wenn die Sammlungszuordnung nicht invers ist.Sehen Sie die beachten in der Dokumentation.

Andere Tipps

Ich verwende Mapping im Code (NH 3.3.1) und habe festgestellt, dass das Hinzufügen von Update (false) und Insert (false) das Problem behebt:

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

Ich habe gerade einen Morgen damit verbracht, diesen Fehler zu beseitigen.Die IndexOutOfRangeException hat mich anfangs auf den falschen Weg geschickt, aber ich habe die Ursache gefunden.Mein Problem betraf eine FluentNHibernate-Klassenzuordnung, die mehrere Komponenten verwendet;das Problem war, dass zwei Eigenschaften versehentlich und falsch ein und derselben Spalte zugeordnet wurden:

vor:

// 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");
          });

nach:

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

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

Wie dies zu einer IndexOutOfRangeException führt, ist mir nicht klar;Ich vermute, dass es ein Array von zugeordneten (Quell-) Eigenschaften und ein Array von Zielspalten gibt, und in diesem Fall ist das Zielarray zu kurz für die Anzahl der Elemente im Array der Quelleneigenschaften, da einige der Zielspalten identisch sind.

Ich denke, aber es lohnt sich, eine Pull-Anfrage für FluentNHibernate zu schreiben, um dies zu überprüfen und eine explizitere Ausnahme auszulösen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top