2010-01-26 7 views
0

Compte tenu des tableaux ci-dessous, je suis en train de retourner toutes les allocations pour une de ressource donnée qui se situent entre une plage de dates à l'aide d'une requête de critères:critères NHibernate requête aide

create table Resources (
    ResourceId integer, 
    ResourceName TEXT not null, 
    BusinessId TEXT not null, 
    OrganizationName TEXT not null, 
    primary key (ResourceId) 
) 

create table Allocations (
    AllocationId integer, 
    StartTime DATETIME not null, 
    EndTime DATETIME not null, 
    PostingTime DATETIME, 
    ResourceId INTEGER, 
    ActivityBaseId INTEGER, 
    primary key (AllocationId), 
    unique (StartTime, EndTime, ResourceId, ActivityBaseId) 
) 

public Resource FetchFor(Resource resource, DateRange range) { 
    var allocations = _session.CreateCriteria<Resource>() 
      .CreateCriteria("Allocations") 
       .Add(Restrictions.Between("EndTime", (DateTime)range.Start, (DateTime)range.End)) 
      .List<Allocation>(); 

     if (allocations.Count() > 0) 
      resource.ReplaceAllocations(allocations); 

     return resource; 
    } 

Je reçois cette exception quand je lance ceci:

failed: NHibernate.QueryException : could not resolve property: EndTime of: Domain.Model.Allocations.Allocation 

Le modèle est mis en correspondance et je peux sauver une ressource et il est associé Affectations sans problème, comme je le fais pour tester cette requête Fetch. Un exemple de ligne de NHib sql: NHibernate: INSERT INTO Attributions (StartTime, EndTime, PostingTime, ResourceId, ActivityBaseId) VALEURS (@ p0, @ p1, @ p2, @ p3, @ p4); sélectionnez last_insert_rowid(); @ p0 = 1/28/2010 12:00:00 AM, @ p1 = 1/28/2010 1:00:00 AM, @ p2 = NULL, @ p3 = 1, @ p4 = 4

Le message d'exception est déroutant car NHib comprend clairement comment mapper Allocation.EndTime. S'il vous plaît:
1) aider les troubles à tirer/nettoyer la requête dans ce poste, et
2) souligner toutes les ressources préférées pour l'apprentissage des requêtes nhib, surtout s'il existe des exemples là-bas. En passant, je me rends compte que je n'utilise pas le paramètre Resource dans l'exemple illustré, car j'ai appliqué le code à partir d'un exemple sur le posting d'Ayende. Si je peux obtenir cette requête de jointure, je la transformerai en une sous-requête pour les performances.

Merci!
Berryl

=== NHib Mapping =====

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true"> 
<class xmlns="urn:nhibernate-mapping-2.2" name="Domain.Model.Allocations.Allocation, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="Allocations"> 
<id name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" unsaved-value="0"> 
    <column name="AllocationId" /> 
    <generator class="identity" /> 
</id> 
<property name="TimeRange" type="Data.UserTypes.AllocationTimeRangeUserType, Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"> 
    <column name="StartTime" not-null="true" unique-key="DomainSignature" /> 
    <column name="EndTime" not-null="true" unique-key="DomainSignature" /> 
</property> 
<property name="PostingTime" type="System.Nullable`1[[System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
    <column name="PostingTime" not-null="false" /> 
</property> 
<many-to-one class="Domain.Model.Resources.Resource, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" foreign-key="Resource_FK" name="Resource"> 
    <column name="ResourceId" unique-key="DomainSignature" /> 
</many-to-one> 
<many-to-one class="Domain.Model.Activities.ActivityBase, Smack.ConstructionAdmin.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" foreign-key="ActivityBase_FK" name="Activity"> 
    <column name="ActivityBaseId" unique-key="DomainSignature" /> 
</many-to-one> 

+0

Pouvez-vous montrer votre cartographie pour l'allocation? –

+0

J'ai ajouté le mappage à la fin de la question. – Berryl

Répondre

1

Il semble que vous n'ayez pas de propriété mappée d'Allocation appelée EndTime. Il n'est donc pas surprenant que vous obteniez cette erreur. La colonne EndTime est mappée à travers le TimeRange de type personnalisé, ce qui signifie que vous vous attendez à une requête sur celle-ci.

Un exemple d'Allocation.cs et le client TimeRange aideraient probablement aussi à comprendre le problème.

+0

C'est un bon point. J'ai vérifié mes mappings et j'ai toutes les propriétés, pas les colonnes. –

+0

Exactement !!! Je sous-estimais totalement le degré auquel NHib présentait vraiment le modèle d'objet, donc "TimeRange.StartTime" est la "chaîne magique" correcte pour rendre cela un jeu d'enfant. Merci! – Berryl

1

J'ai essayé de reproduire votre problème, mais sans succès. Étant donné que vous ne l'utilisez ressource dans votre requête, vous pouvez essayer de simplifier les choses, telles que:

var allocations = _session.CreateCriteria<Allocation>() 
      .Add(Restrictions.Between("EndTime", (DateTime)range.Start, (DateTime)range.End)) 
     .List<Allocation>(); 

Je l'ai fait quelques requêtes de jointure, je peux fournir l'exemple suivant, j'espère que cela aide:

 public IList<ItemOrder> GetItemOrderByCriteria(int? itemNumber, int? warehouseNumber, DateTime? orderPickDate, string orderStoreNum, string statusCode) 
    { 
     try 
     { 
      NHibernate.ICriteria criteria = NHibernateSession.CreateCriteria(typeof(Core.SuggestedOrders.ItemOrder)); 

      if (itemNumber.HasValue) 
       criteria.CreateCriteria("Item", "Item").Add(Expression.Eq("Item.ItemNumber", itemNumber.Value)); 

      if (warehouseNumber.HasValue) 
       criteria.CreateCriteria("Warehouse", "Warehouse").Add(Expression.Eq("Warehouse.WarehouseNumber", warehouseNumber)); 

      if (!String.IsNullOrEmpty(orderStoreNum)) 
       criteria.Add(Expression.Eq("OrdStoreNum", orderStoreNum)); 

      if (!String.IsNullOrEmpty(statusCode)) 
       criteria.Add(Expression.Eq("StatusCode", statusCode)); 

      if (orderPickDate.HasValue) 
      { 
       DateTime minPickDate = new DateTime(orderPickDate.Value.Year, orderPickDate.Value.Month, orderPickDate.Value.Day, 0,0,0); 
       DateTime maxPickDate = new DateTime(orderPickDate.Value.Year, orderPickDate.Value.Month, orderPickDate.Value.Day, 23,59,59); 

       criteria.Add(Expression.Between("OrdPickDate", minPickDate, maxPickDate)); 
      } 

      return criteria.List<Core.SuggestedOrders.ItemOrder>(); 
     } 
     catch (NHibernate.HibernateException he) 
     { 
      DataAccessException dae = new DataAccessException("NHibernate Exception", he); 
      throw dae; 
     } 

    } 
Questions connexes