2010-01-20 4 views
1

J'ai une classe appelée LoanApplication, et une propriété de collection appelée Workflow. Dans le fichier de mappage, je définis l'ordre de récupération des enregistrements de flux de travail à trier par date, de sorte que le flux de travail en cours est toujours le premier élément de la liste.NHibernate - crée des critères basés sur une propriété qui est une liste

Maintenant, je veux interroger par le flux de travail actuel pour obtenir LoanApplications qui sont dans une étape de flux de travail spécifique en utilisant l'API Criteria. Je ne suis pas vraiment sûr de savoir comment faire ça. Voici comment je délimiterai la collection Workflow:

<bag name="ApplicationWorkflow" table="PreApplication.ApplicationWorkflow" generic="true" inverse="true" order-by="StartDate DESC" 
    cascade="all" lazy="true"> 
    <key column="ApplicationID" /> 
    <one-to-many class="ApplicationWorkflow" /> 
</bag> 

Voici comment je suis en train de récupérer des applications (ce qui est là où je dois ajouter le filtre par courant fonctionnalité de workflow):

public IList<Model.PreApplication.Application> GetCompletedApplications() 
    { 
     IList<Model.PreApplication.Application> result = null; 

     using (ITransaction transaction = this.Session.BeginTransaction()) 
     { 
      result = this.Session.CreateCriteria<Model.PreApplication.Application>() 
       .AddOrder(new Order("EnteredDate", false)) 
       .List<Model.PreApplication.Application>(); 

      transaction.Commit(); 
     } 

     return result; 
    } 

Merci pour tout Aidez-moi!

Répondre

2

Vous avez donc besoin de lister les applications dont le flux de travail actuel est à une étape spécifique? Vous pouvez utiliser une sous-requête pour rejoindre uniquement le flux de travail en cours, puis vous limiter à une étape spécifique.

SQL souhaitée ...

select 
    ... 
from 
    Application app 
    inner join ApplicationWorkFlow currWorkFlow on app.id = currWorkFlow.application_id 
where 
    currWorkFlow.id = (
     select top 1 topFlow.id 
     from ApplicationWorkFlow topFlow 
     where topFlow.application_id = app.id 
     order by topFlow.StartedDate desc 
    ) 
    and currWorkFlow.step = @step 

les critères pour vous y ...

session.CreateCriteria<Application>("app") 
    .CreateAlias("ApplicationWorkFlow", "currWorkFlow", NHibernate.SqlCommand.JoinType.InnerJoin) 
    .Add(Subqueries.PropertyEq("currWorkFlow.id", 
     DetachedCriteria.For<ApplicationWorkFlow>("topFlow") 
      .SetMaxResults(1) 
      .SetProjection(Projections.Property("topFlow.id")) 
      .AddOrder(Order.Desc("topFlow.StartDate")) 
      .Add(Restrictions.EqProperty("app.id", "topFlow.Application.id")))) 
    .Add(Restrictions.Eq("currWorkFlow.step", step)) 
    .List<Application>(); 
+0

Je voudrais pouvoir vous donner 10 upvotes. Merci! –

0

Je suggère d'ajouter simplement une référence au dernier workflow actif. Les critères seront beaucoup plus simples :)

public void AddLatestWorkflow(Workflow wf) 
{ 
    this.Workflows.Add(wf); 
    this.LatestWorkflow = wf; 
} 
+0

Je ne sais pas de quoi vous parlez. Ajouter une autre propriété qui est le dernier flux de travail en plus de conserver la liste de tous les flux de travail? Si c'est ce que vous dites, pouvez-vous me montrer comment obtenir la propriété qui est le dernier flux de travail? –

+0

J'ajoute un exemple de code. – dariol

1

Comment au sujet de cette requête SQL?

SELECT * FROM Application app 
JOIN 
    (SELECT * FROM ApplicationWorkFlow aflo WHERE aflo.step = @step) AS aflo 
WHERE aflo.application_id = app.id 

requête simplifiée en utilisant des critères

var applications = 
    Session.CreateCriteria<Application>() 
      .CreateAlias("ApplicationWorkFlow", "appflo", JoinType.LeftOuterJoin) 
      .Add(Restrictions.Eq("appflo.Step", step)) 
      .List<Application>(); 

Critères de requête correspondant à l'aide des critères détachés

var detached = DetachedCriteria.For<ApplicationWorkFlow>() 
           .SetProjection(Projections.Id()) 
           .Add(Restrictions.Eq("Step", step)); 

var applications = 
     Session.CreateCriteria<Application>() 
       .CreateAlias("ApplicationWorkFlow", "appflo", JoinType.LeftOuterJoin) 
       .Add(Subqueries.PropertyIn("appflo.Id", detachedCriteria)) 
       .List<Application>(); 

Quelqu'un pourrait-il s'il vous plaît me dire si les deux requêtes ci-dessus sont les mêmes? Ils génèrent le même sql dans mon cas. Si elles sont identiques, pourquoi utiliser les DetachedCriteria?

+0

Merci! Votre première requête simplifiée était beaucoup plus simple et m'a aidé à obtenir ce dont j'avais besoin. +1 – tofortier

Questions connexes