2010-10-19 7 views
1

Je suis en train de créer une application Web avec MVC et NHibernate. Maintenant, quand je veux obtenir des informations sur la base de données, je reçois un index était hors de l'exception.Obtenir un index était une exception hors plage avec NHibernate

La situation actuelle est la suivante.

J'ai obtenu les fichiers de mappage de trois tables de base de données:
Une table pour stocker un groupe avec une relation un-à-plusieurs avec 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> 

Une table pour stocker un abonné avec une relation un-à-plusieurs avec le sous-groupe d'abonnés.

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

et enfin le mappage de subscriberingroup

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

Dans la classe d'abonné J'ai la propriété suivante pour l'un à-plusieurs:

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

Dans la classe de groupe je la propriété suivante pour la relation un-à-manu:

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

Et dans la classe SubscriberInGroup je donne les résultats suivants pour le nombre à une relation:

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

Quand je veux obtenir le SubscriberInGroup avec certaines valeurs dans le tableau de groupe et abonné i obtenir un indice sur exception de gamme.

Cela se produit avec la requête suivante:

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

Lors de l'exécution de cette requête, je suis l'exception. La chose étrange est quand je fais ceci:

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

cela fonctionne comme je m'attendais aussi. La méthode GetSubscriberInGroup ressemble à ceci:

publique IQueryable GetSubcribersInGroup() { _session.Linq de retour(); }

Je voudrais que cela fonctionne comme dans la première méthode, car la table peut contenir plusieurs entrées et ToList() n'est pas une option. Donc, si quelqu'un a une idée de la raison pour laquelle je reçois cette erreur et comment je la fais fonctionner correctement s'il vous plaît partager vos connaissances!

EDIT:

est inférieure à la trace de la pile:

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) 

Merci,

Gerard

+0

pouvez-vous également publier la trace de la pile? – Jaguar

+0

J'ai ajouté la trace de la pile, j'espère que vous pouvez comprendre ce qui ne va pas! – Gerard

Répondre

1

Dans l'un de vos mappings, je vois que vous utilisez un ordinal. Est-ce utilisé pour trier vos abonnés dans un certain groupe? Assurez-vous que la valeur est correcte et que les valeurs sont correctement mises à jour dans la base de données. Par exemple, si vous avez seulement 2 enregistrements et que votre ordinal commence à 10, vous aurez très probablement cette erreur car une liste avec 9 éléments vides (nullables) sera retournée. Lors de l'exécution d'une condition where, une exception sera levée.

edit: Je me demandais juste pourquoi vous voulez commander des abonnés dans un groupe de quelque chose .. Si ce n'est pas vraiment nécessaire, vous pouvez essayer d'utiliser un sac. Cela ne nécessite pas la présence de la colonne ordinale

+0

Que je n'ai pas pensé à ça! Là où les lignes avec des ordinaux commençant à 3 au lieu de 0 ... J'ai également changé la liste en un sac et supprimé la colonne ordinale. Cela a résolu mon problème! Remercier. – Gerard

0

LINQ to NHibernate doit traduire votre expression LINQ to SQL.Dans cet esprit

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

semble problématique. LINQ to NHibernate devrait avoir la capacité de générer des requêtes SQL qui convertit un Group.Id à une chaîne et la comparer à une autre chaîne ... alors que dans votre exemple de travail

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

LINQ to NHibernate seulement doit générer sql pour comparer deux guids.

On Ayende's blog post parler de LINQ à NHibernate Zoltan Hubai a laissé un commentaire où il obtenait une exception semblable à la vôtre avec le code:

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

et la réponse de Ayende était:

`` Je don Je ne pense pas que nous supportons "d.Nom.ToLower(). StartsWith (" a ")" pour le moment. ''

+0

Merci pour la réponse. J'ai déjà essayé de changer cette ligne pour que le s1 soit un Guid dans ma déclaration de linq et cela n'a fait aucune différence. – Gerard

Questions connexes