5

我已经阅读了所有帖子并且知道 IndexOutOfRange 通常会发生,因为一个列被引用了两次。但是根据我的映射,我看不出这是如何发生的。在配置中使用 SHOW_SQL 为 true 时,我看到一个 Insert 到Events表中,然后是一个IndexOutOfRangeException引用RadioButtonQuestions表的。我看不到它尝试使用的生成异常的 SQL。我尝试使用 AutoMapping,现在已将ClassMap这两个类切换为完整,以尝试缩小问题范围。

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:插入事件(EventDate,标题)值(@p0,@p1);@p0 = 5/21/2012 12:32:11 PM [类型:日期时间(0)],@p1 = '我的测试事件' [类型:字符串(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 不会处于双向关系,从我读过的内容来看)。EventFWIW我还通过删除from尝试将其作为单向关系RadioButtonQuestion,但仍然导致相同的异常。

4

3 回答 3

7

我在代码中使用映射(NH 3.3.1),我注意到添加 Update(false) 和 Insert(false) 可以解决问题:

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);
});
于 2012-08-29T18:09:31.753 回答
5

您有一个双向关联,因此一侧应标记为 Inverse() 并且只能是 RadioButtonQuestions 集合。如果您希望集合成为所有者,则必须在 RadioButtonQuestion 类中删除对事件的引用。

此外,RadioButtonQuestions 表中的 EventId 列不可为空,如果集合映射不反向,这可能会导致问题。请参阅文档中的注释

于 2012-05-21T18:41:48.037 回答
1

我刚刚花了一个上午的时间来根除这个错误。IndexOutOfRangeException 最初让我走错了路,但我找到了原因。我的问题涉及使用多个组件的 FluentNHibernate 类映射;问题是两个属性被无意中错误地映射到同一列:

前:

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

后:

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

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

这如何导致 IndexOutOfRangeException 对我来说并不明显。我猜有一个映射(源)属性数组和一个目标列数组,在这种情况下,目标数组对于源属性数组中的项目数来说太短了,因为一些目标列是相同的.

我认为,但值得为 FluentNHibernate 编写一个拉取请求来检查这一点并抛出更明确的异常。

于 2018-10-16T11:45:10.767 回答