2010-05-27 5 views
2

J'ai un Entity Framework 4.0 Entity Object appelé Revision avec les dates Nullable DateEffectiveFrom et DateEffectiveTo. Je me demandais s'il y avait un moyen sténographie d'interroger RevisionHistory est un objet en fonction d'une date QueryDate particulière au lieu d'avoir à utiliser la structure de requête suivante:Entity Framework Fonction de requête personnalisée

var results = EntityObject.Revisions.Where(x => 
    (x.DateEffectiveFrom == null && x.DateEffectiveTo == null) || 
    (x.DateEffectiveFrom == null && x.DateEffectiveTo >= QueryDate) || 
    (x.DateEffectiveFrom <= QueryDate && x.DateEffectiveTo == null) || 
    (x.DateEffectiveFrom <= QueryDate && x.DateEffectiveTo >= QueryDate)); 

J'ai essayé de créer la fonction booléenne suivante dans la Revision classe:

partial class Revision 
{ 
    public bool IsEffectiveOn(DateTime date) 
    { 
     return (x.DateEffectiveFrom == null && x.DateEffectiveTo == null) || 
      (x.DateEffectiveFrom == null && x.DateEffectiveTo >= date) || 
      (x.DateEffectiveFrom <= date && x.DateEffectiveTo == null) || 
      (x.DateEffectiveFrom <= date && x.DateEffectiveTo >= date)); 
    } 
    ... 
} 

Et puis mettre à jour la requête:

var results = EntityObject.Revisions.Where(x => x.IsEffectiveOn(QueryDate)); 

mais évidemment d ne traduisent pas en SQL. Toutes les idées seraient très appréciées.

Répondre

1

Vous pouvez essayer Predicate Builder, et voir si cela se traduit par le SQL approprié.

+0

Merci Robert - Cela semblait faire l'affaire pour toutes les requêtes IQuerable (c.-à-d. DataContext.Revisions). Toutes les idées pour les scénarios IEnumerable . PS - J'apprécie également l'explication détaillée de l'utilisation des prédicats dans l'article. – Josh

+0

Pour les scénarios IEnumerable, vous pouvez voir si [Dynamic Linq] (http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic- query-library.aspx) fonctionne. Notez que Dynamic Linq n'est pas fortement typé ... vous devez composer vos prédicats en tant que chaînes. –

0

La façon dont vous créez cette requête dépend en partie de ce que signifie NULL pour EffectiveFrom et EffectiveTo.

Si EffectiveFrom est NULL, cela devrait-il être efficace pour toutes les dates avant EffectiveTo, et l'inverse pour NULL EffectiveTo? Si tel est le cas, vous pouvez utiliser DateTime.MinValue en remplacement des valeurs NULL EffectiveFrom et DateTime.MaxValue pour EffectiveTo. À ce moment-là, vous pouvez simplement utiliser des requêtes ENTRE style:

Where(x => x.DateEffectiveFrom > QueryDate < x.DateEffectiveTo); 
+0

J'apprécie la réponse Dave, mais j'essaie d'éviter cette situation si je le peux. – Josh

3

Vous pouvez faire votre fonction retourne un Expression, plutôt que d'un bool:

partial class Revision 
{ 
    public static Expression<Func<Revision, bool>> IsEffectiveOn(DateTime date) 
    { 
     return x => (x.DateEffectiveFrom == null && x.DateEffectiveTo == null) || 
      (x.DateEffectiveFrom == null && x.DateEffectiveTo >= date) || 
      (x.DateEffectiveFrom <= date && x.DateEffectiveTo == null) || 
      (x.DateEffectiveFrom <= date && x.DateEffectiveTo >= date)); 
    } 
} 

Ensuite, vous pouvez l'utiliser:

var predicate = Revision.IsEffectiveOn(DateTime.Now); 
var results = EntityObject.Revisions.Where(predicate); 

... et cela se traduira par SQL.

+0

Merci Craig - J'ai donné la réponse à Robert comme l'article qu'il a référé a pointé vers la solution que vous avez donnée ci-dessus. Je bosse votre réponse aussi si je pouvais parce que j'apprécie le code. – Josh

+0

@Josh: Je l'ai bousculé pour vous. –

+0

@Robert: Merci ... les joies d'être un débutant: P – Josh

Questions connexes