Pregunta

He leído todos los mensajes y saber que IndexOutOfRange generalmente ocurre debido a que una columna se hace referencia a dos veces.Pero no veo cómo eso está ocurriendo basado en mis asignaciones.Con SHOW_SQL cierto en el config, veo una Inserción en la Events tabla y, a continuación, un IndexOutOfRangeException que se refiere a la RadioButtonQuestions tabla.No puedo ver el SQL que está tratando de usar que genera la excepción.He intentado utilizar la Autoasignación y ahora han pasado a la plena ClassMap para estas dos clases para tratar de reducir el 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();
    }
}

El SQL generado es correcto:

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

Este es el uso de NH 3.3.0.4000 y FNH 1.3.0.727.Cuando intento guardar un nuevo Evento (con un RadioButtonQuestion adjunto) veo

NHibernate:INSERT INTO Eventos (EventDate, Título) VALUES (@p0, @p1);@p0 = el 5/21/2012 12:32:11 PM [Tipo:DateTime (0)], @p1 = 'Mi Evento de Prueba" [Tipo:String (0)] NHibernate:select @@IDENTITY

Eventos.Pruebas.Eventos.Tareas.EventTasksTests.CanCreateEvent:NHibernate.PropertyValueException :Error de la deshidratación valor de la propiedad para Eventos.Dominio.RadioButtonQuestion._Events.Dominio.Evento.RadioButtonQuestionsIndexBackref ----> Sistema.IndexOutOfRangeException :Un SqlCeParameter con ParameterIndex '3' no está contenida en este SqlCeParameterCollection.

Así que si una columna es realmente la que se hace referencia dos veces, ¿cuál es el problema con mi FNH config que está causando el comportamiento?Estoy intentando por un bidirection relación (Uno de los Eventos Tiene Muchas Botón de Radio de Preguntas) con el pedido (voy a mantenerlo ya que NH no en un bidir relación, por lo que he leído).Por lo que vale también probé esto como una relación unidireccional mediante la eliminación de la Event de RadioButtonQuestion y todavía causado la misma excepción.

¿Fue útil?

Solución

Usted tiene una asociación bidireccional, de manera que un lado debe ser marcado como Inversa() y que sólo puede ser el RadioButtonQuestions colección.Si desea que la recogida de ser el propietario, usted tiene que quitar la referencia al evento en su RadioButtonQuestion clase.

Además, el EventId columna en la tabla RadioButtonQuestions no acepta valores null, lo que puede causar problemas, si el mapeo de la colección no es inversa.Ver el nota en la documentación.

Otros consejos

Estoy utilizando la cartografía en el código (NH 3.3.1) y he observado que la adición de Actualización(falso) y de Inserción(falso) cura el 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);
});

Me acaba de pasar una mañana de enraizamiento este error.El IndexOutOfRangeException enviado a mí por el camino equivocado en un principio, pero he encontrado la causa.Mi problema de que se trate de un FluentNHibernate clase de mapa que utiliza varios componentes;el problema era que las dos propiedades fueron inadvertedly y asignan incorrectamente a una y la misma columna:

antes:

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

después de:

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

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

Cómo esto se traduce en un IndexOutOfRangeException no es obvio para mí;Supongo que hay una gran variedad de mapeado (fuente) y las propiedades de una matriz de columnas de destino, y en este caso la matriz de destino es demasiado corta para que el número de elementos en el origen de las propiedades de la matriz, debido a que algunas de las columnas de destino son idénticos.

Creo, pero vale la pena escribir un pull request para FluentNHibernate comprobar esto y lanzar de forma más explícita la excepción.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top