使用NHibernate获取索引超出了范围异常

时间:2010-10-19 14:38:34

标签: c# linq nhibernate nhibernate-mapping linq-to-nhibernate

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

目前的情况如下。

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

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

在SubscriberInGroup类中,我有以下多对一关系:

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

当我想让SubscriberInGroup获得组和订阅者表中的某些值时,我得到一个超出范围异常的索引。

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

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

它的工作方式也和我预期的一样。 GetSubscriberInGroup方法如下所示:

public IQueryable GetSubcribersInGroup()     {         return _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 个答案:

答案 0 :(得分:1)

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

编辑:只是想知道为什么要在一组东西中订购订阅者..如果不是真的有必要,你可以尝试使用一个包。这不需要存在序数列

答案 1 :(得分:0)

linq-to-nhibernate必须将您的Linq表达式转换为SQL。考虑到这一点

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

看起来有问题。 linq-to-nhibernate必须能够生成将Group.Id转换为String并将其与另一个String进行比较的sql ...而在您的工作示例中

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

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

Ayende's blog post上谈论linq-to-nhibernate Zoltan Hubai留下了一条评论,在那里他得到了一个类似于你的例外代码:

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

和Ayende的回答是:

``我认为我们不支持“d.Name.ToLower()。此刻,StartsWith(”a“)”。“

相关问题