2011-12-16 3 views
2

Dans ma base de données, j'ai des tables qui ont un attribut int DeleteState. Je veux une méthode générique pour interroger ces tables. En d'autres termes, une méthode qui fait cela: Context.Table.Where(x => x.DeleteState == 0).Méthode de requête générique dans Entity Framework

Je pensais que je pouvais le faire:

public static class Extensions 
{ 
    public static IQueryable<T> Exists<T>(this IQueryable<T> qry) where T : IDeletable 
    { 
    return qry.Where(x => x.DeleteState == 0); 
    } 
} 

IDeletable est la suivante:

public interface IDeletable 
{ 
    int DeleteState { get; set; } 
} 

Maintenant, je ne dispose que d'ajouter le IDeletable dans le modèle EF:

public partial class Table : EntityObject, IDeletable { ... } 

Je l'ai fait avec le mécanisme de modèle.

Malheureusement, cela ne fonctionne pas :(Il compile très bien, mais jette à l'exécution:

Unable to cast the type 'Table' to type 'IDeletable'. LINQ to Entities only supports casting Entity Data Model primitive types

si je l'appelle comme ça:

Context.Table.Exists(); 

Comment puis-je résoudre ce Pourriez-vous penser à un correctif ou à une méthode différente pour obtenir des résultats similaires? Thx

Répondre

0

Tsss, c'est la réponse: Linq Entity Framework generic filter method

J'ai oublié le class ici:

... où T: classe, IDeletable

+0

Si votre solution fonctionne erreur que vous aviez à l'exécution ne me semble pas bon. – Vince

+0

@vince: veuillez élaborer.Les exceptions ne sont pas bonnes en général :) – duedl0r

+0

Votre solution fonctionne-t-elle? avez-vous essayé le mien? Je viens de dire que si cela fonctionne par la classe addind à la contrainte générique, l'erreur "LINQ to Entities ne supporte que le cast des types primitifs Entity Data Model" n'a pas de sens. Cela n'a pas vraiment d'importance, ce ne sera pas la première exception sans ^^ – Vince

0

Le problème que vous avez est que Entity Framework ne peut que rk avec un arbre d'expression. Votre fonction exécute une requête directement au lieu de créer un arbre d'expression. Une solution plus simple serait d'ajouter un Model Defined Function.

Une fonction définie par un modèle peut être appelée directement sur une instance de votre contexte.

+0

Thx, bonjour NT. – duedl0r

0

Avez-vous essayé de convertir vos objets en IDeletable avant de lancer une requête? par exemple.

public static IQueryable<T> Exists<T>(this IQueryable<T> qry) 
{  
    return qry.Select<T, IDeletable>(x => x).Where(x => x.DeleteState == 0).Cast<T>(); 
} 

Je ne l'ai pas testé ce code, cependant, l'erreur sonne une cloche et je me souviens que je devais faire quelque chose de similaire.

+0

Hmm, j'ai la même exception d'exécution. Aussi un inconvénient à cela est que je reçois un type différent de la sélection. Ce n'est plus T mais IDeletable, non? – duedl0r

+0

@ duedl0r - Oui, mais vous pouvez toujours le renvoyer 'Où (x => x.DeleteState == 0) .Cast ()'. Voir ma source mise à jour, vous obtiendrez toujours le problème si votre force encore T est 'IDeletable' dans la déclaration de la méthode. – James

0

Peut-être:

public static IQueryable<T> Exists<T>(this IQueryable<T> qry) 
{ 
    return qry.Where(x => (!typeof(IDeletable).IsAssignableFrom(x.GetType()) || typeof(IDeletable).IsAssignableFrom(x.GetType()) && ((IDeletable)x).DeleteState == 0)); 
} 
Questions connexes