Linq méthode d'extension
J'ai souvent besoin de limiter Sélectionne par les champs comme publishStart
, publishEnd
, active
J'ai ces champs de plusieurs tables différentes. Donc, seules les lignes doivent être sélectionnés, qui sont
a: active == true;
b: publishStart < now;
c: publishEnd > now;
Ainsi, par exemple:
db.myTable.SingleOrDefault(a => (a.ID == _theID
//now the active and start-end part:
&& ((a.publishEnd > DateTime.Now) || (a.publishEnd == null))
&& ((a.publishStart <= DateTime.Now) || (a.publishStart == null))
&& a.active == true));
C'est un peu long, donc je me demande si il est possible de créer un (extension?)-méthode:
db.myTable.SingleOrDefault(a => (a.ID == _theID).isActive()
où la isActive()
offre les 3 lignes de l'extrait ci-dessus.
Comment pourrais-je faire cela?
Est-il une meilleure façon de nettoyer le code?
Ce sont toutes dans des tables distinctes, à droite? Pas un seul tableau est exposé par le contexte? Je demande parce que vous indiquez dans le préambule que les propriétés sont sur des tables séparées, alors que vous utilisez un seul contexte dans le filtre. Si ils sont tous sur la même table, c'est facile, si elles sont sur des tables différentes, il modifie le droit de réponse énormément.
Dans ce cas, vous auriez besoin d'appeler
Dans ce cas, vous auriez besoin d'appeler
IsActive
avant SingleOrDefault
de sorte qu'il peut filtrer les éléments actifs avant de vous en prendre qu'un, à moins qu'il n'y a qu'un seul élément avec l'ID.OriginalL'auteur reinhard | 2013-01-08
Vous devez vous connecter pour publier un commentaire.
De définir une extension que vous avez besoin d'une classe statique. Vous pouvez mettre ceci dans quel espace de noms que vous aimez, n'oubliez pas de l'inclure dans votre usage.
Avis
YourEntityType
. Ce est utilisé pour s'assurer que la méthode est au courant de l'existence depublishStart
,publishEnd
, etactive
. Ce sera soit la classe qui implémente ces champs ou d'un contrat (interface) qui les définit.Vous serait alors appeler cela de la sorte:
Plus sur les méthodes d'extension ici: http://msdn.microsoft.com/en-us/library/bb383977.aspx
Comme il ya beaucoup de commentaires surgissent tout plus de l'endroit, je vais ajouter ici une brève explication de l'interface de la solution...
Il n'est pas clair dans la question de savoir s'il existe ou non une mise en œuvre commune pour les trois champs filtrés ou une interface pour les définir. Si pas, pour la ci-dessus pour travailler, vous n'aurez pas:
YourEntityType
avecYourBaseEntityType
.YourEntityType
avecIYourContract
.IQueryable<T>
au lieu deIEnumerable<T>
?Cela ne fonctionnera pas dans un appel à
SingleOrDefault
qui est ce que l'OP demande.Je préfère utiliser
IQueryable<T>
que j'ai eu le polymorphisme des problèmes dans le passé avecIEnumerable<T>
. Étant donné qu'il existe des extensions pour les deuxIEnumerable<T>
etIQueryable<T>
, au retour d'uneIEnumerable<T>
peut entraîner le mauvais extensions être appelé plus loin dans la chaîne résultant dans l'énumération plutôt que le report de requêtes.C'est une question de si vous voulez être l'exécution de la requête sur la base de données, ou le retour de tous les éléments et de filtrage dans le code C#. Filtrage dans la DB est presque toujours préférable, lorsque c'est possible, mais il n'est pas toujours possible.
Il n'y a pas besoin de faire cette méthode générique et puis contraindre le type de paramètre à un type, à moins que tous les types de ces trois propriétés, sont modélisés à l'aide de l'héritage - quelque chose que je veux vraiment de ne pas suggérer de le faire dans la plupart des cas.
OriginalL'auteur Paul Fleming
Il suffit de définir une interface comme ceci
et l'ajouter à toutes les classes.
Maintenant, vous pouvez utiliser cette méthode d'extension
sur chaque instance de mise en œuvre de
IHaveAActivityPeriod
.J'ai complètement raté la possibilité de construire une extension de la méthode qui effectue le filtrage d'une séquence au lieu de regarder une seule entité à la fois. Il suffit de prendre l'extension de la méthode de flem de répondre à un jeter dans l'interface comme type de contrainte.
C'est vrai, mais il n'y a pas vraiment de bonne solution qui est traduisible en SQL (sans un fournisseur personnalisé) et il a donc décidé de présenter une LINQ to Objects solution.
OriginalL'auteur Daniel Brückner
OriginalL'auteur I4V