代码之家  ›  专栏  ›  技术社区  ›  Gerard

获取索引超出范围,NHibernate除外

  •  1
  • Gerard  · 技术社区  · 14 年前

    我目前正在用MVC和NHibernate构建一个Web应用程序。现在,当我想从数据库中获取信息时,我得到了一个超出范围的索引异常。

    目前情况如下。

    我得到了三个数据库表的映射文件:
    用于存储与subscriptingroup具有一对多关系的组的表。

    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
      <joined-subclass name="CMS.Business.Entities.Subscriber, CMS.Business.Entities" extends="CMS.Business.Entities.BaseEntity, CMS.Business.Entities" table="CMS_Subscriber">
        <key column="Id" />
        <property name="Email" />
        <property name="FirstName" />
        <property name="Lastname" />
        <list name="SubscriberInGroup" cascade="all" table="CMS_SubscriberInGroup">
          <key column="SubscriberId" />
          <index column="Ordinal" />
          <one-to-many class="CMS.Business.Entities.SubscriberInGroup, CMS.Business.Entities" />
        </list>
      </joined-subclass>
    </hibernate-mapping>  
    

    一种表,用于存储与订阅组具有一对多关系的订阅服务器。

    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
      <joined-subclass name="CMS.Business.Entities.Group, CMS.Business.Entities" extends="CMS.Business.Entities.BaseEntity, CMS.Business.Entities" table="CMS_Group">
        <key column="Id" />
        <property name="Name" />
        <list name="SubscriberInGroup" cascade="all" lazy="false" table="CMS_SubscriberInGroup">
          <key column="GroupId" />
          <index column="Ordinal" />
          <one-to-many class="CMS.Business.Entities.SubscriberInGroup, CMS.Business.Entities" />
        </list>
      </joined-subclass>
    </hibernate-mapping>   
    

    最后是下标群映射

    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
        <joined-subclass name="CMS.Business.Entities.SubscriberInGroup, CMS.Business.Entities" extends="CMS.Business.Entities.BaseEntity, CMS.Business.Entities" table="CMS_SubscriberInGroup">
            <key column="Id" />
            <property name="ConfirmationDate" />
            <property name="ConfirmationIP" />
            <property name="SubscribeDate" />
            <property name="SubscribeIP" />
            <property name="SubscribeLocation" />
            <property name="UnSubscribeDate" />
            <property name="UnSubscribeIP" />
            <property name="UnSubscribeLocation" />
            <many-to-one name="Subscriber" class="CMS.Business.Entities.Subscriber, CMS.Business.Entities" column="SubscriberId" />
            <many-to-one name="Group" class="CMS.Business.Entities.Group, CMS.Business.Entities" column="GroupId" />
        </joined-subclass>
    </hibernate-mapping>
    

    在订阅服务器类中,对于一对多关系,我具有以下属性:

    /// <summary>
            /// The subscriberingroup where the subscriber is registered.
            /// </summary>
            [List(4, Name = "SubscriberInGroup", Cascade = CascadeStyle.All)]
            [NHibernate.Mapping.Attributes.Key(5, Column = "SubscriberId")]
            [Index(6, Column = "Ordinal")]
            [OneToMany(7, ClassType = typeof(SubscriberInGroup))]
            public virtual IList<SubscriberInGroup> SubscriberInGroup { get; set; }
    

    在组类中,对于一对一关系,我具有以下属性:

    /// <summary>
            /// The subscribers of this group.
            /// </summary>
            [List(4, Name = "SubscriberInGroup", Cascade = CascadeStyle.All)]
            [Key(5, Column = "GroupId")]
            [Index(6, Column = "Ordinal")]
            [OneToMany(7, ClassType = typeof(SubscriberInGroup))]
            public virtual IList<SubscriberInGroup> SubscriberInGroup { get; set; }
    

    在下标群类中,对于多对一关系,我有以下内容:

    /// <summary>
            /// The subscriber.
            /// </summary>
            [ManyToOne(8, ClassType = typeof(Subscriber), Column="SubscriberId", ForeignKey = "FK_Subscriber_SubscriberInGroup")]
            public virtual Subscriber Subscriber { get; set; }
            /// <summary>
            /// The group which is subscribed to.
            /// </summary>
            [ManyToOne(9, ClassType = typeof(Group), Column = "GroupId", ForeignKey = "FK_Group_SubscriberInGroup")]
            public virtual Group Group { get; set; }
    

    当我想要在group和subscriber表中获取具有特定值的subscriberinggroup时,我会得到一个超出范围的索引异常。

    以下查询会发生这种情况:

    SubscriberService.GetSubscriberInGroup(viewModel.EmailAddress, new Guid(s));
                        SubscriberService.GetSubcribersInGroup().Where(
                            g => g.Subscriber.Email == viewModel.EmailAddress && g.Group.Id.ToString().Equals(s1)).
                            FirstOrDefault();
    

    var list = SubscriberService.GetSubcribersInGroup().ToList();
                    var subscriberInGroup =
                        list.FirstOrDefault(
                            g => g.Subscriber.Email.Equals(viewModel.EmailAddress) && g.Group.Id == new Guid(s1));
    

    它也像我预期的那样工作。getsubscriberinggroup方法如下:

    公共IQueryable GetSubcribersInGroup()。 { 返回_session.linq(); }

    我希望它像第一个方法一样工作,因为表可以包含许多条目,而tolist()不是一个选项。所以,如果有人知道我为什么会犯这个错误,以及我如何使它正常工作,请分享你的知识!

    编辑:

    下面是堆栈跟踪:

     at System.SZArrayHelper.get_Item[T](Int32 index)
       at NHibernate.Linq.Visitors.EntityExpressionVisitor.VisitMethodCall(MethodCallExpression expr)
       at NHibernate.Linq.Visitors.ExpressionVisitor.Visit(Expression exp)
       at NHibernate.Linq.Visitors.EntityExpressionVisitor.FindEntity(Expression expr, Boolean findFirst)
       at NHibernate.Linq.Visitors.BinaryCriterionVisitor.VisitMethodCall(MethodCallExpression expr)
       at NHibernate.Linq.Visitors.ExpressionVisitor.Visit(Expression exp)
       at NHibernate.Linq.Visitors.BinaryCriterionVisitor.GetBinaryCriteria(ICriteria rootCriteria, ISession session, BinaryExpression expr, ComparePropToValue comparePropToValue, ComparePropToProp comparePropToProp, CompareValueToCriteria compareValueToCriteria, ComparePropToCriteria comparePropToCriteria)
       at NHibernate.Linq.Visitors.WhereArgumentsVisitor.VisitBinaryCriterionExpression(BinaryExpression expr)
       at NHibernate.Linq.Visitors.WhereArgumentsVisitor.VisitBinary(BinaryExpression expr)
       at NHibernate.Linq.Visitors.ExpressionVisitor.Visit(Expression exp)
    

    谢谢,

    热拉尔

    2 回复  |  直到 14 年前
        1
  •  1
  •   Rob    14 年前

    在其中一个映射中,我看到您使用的是序数。这是否用于对某个组中的订阅用户进行排序? 确保它具有正确的值,并且在数据库中以正确的方式更新这些值。例如,如果只有2条记录,并且序号从10开始,则很可能会出现此错误,因为将返回包含9个空(可以为空)项的列表。执行Where条件时,将引发异常。

    编辑 :只是想知道为什么要订购一组某物中的订户。如果没有必要的话,你可以试着用一个袋子。这不需要有序数列

        2
  •  0
  •   Handcraftsman    14 年前

    linq to nhibernate必须将linq表达式转换为sql。考虑到这一点

    g.Group.Id.ToString().Equals(s1)
    

    看起来有问题。linq-to-nhibernate必须能够生成将group.id转换为字符串并将其与另一个字符串进行比较的SQL…而在你的工作例子中

    g.Group.Id == new Guid(s1)
    

    linq to nhibernate只需要生成SQL来比较两个guid。

    Ayende's blog post 在谈到Linq与Nhibernate Zoltan Hubai的谈话时,他留下了一条评论,他得到了一个与您类似的例外代码:

    where d.Name.ToLower().StartsWith("a") 
    

    Ayende的回答是:

    ``我认为我们目前不支持“d.name.tolower().startswith(”A”)。