1

J'utilise EF 6 et .net 4.5. J'ai une table "Documents" avec le PK "DocumentId" (Int) et une autre colonne, "Titre". J'ai une autre table appelée "DocumentFilters" avec les colonnes "DocumentId" (Int) et "DocGUID" (Guid). Il y a un FK sur "Doc Id" entre les deux tables. Il s'agit d'une relation un à plusieurs entre les tables Documents et DocumentFilters. Le modèle ressemble à ceci:Utilisation de Dynamic LINQ Où dans une relation Entity Framework un-à-plusieurs

DocModel

Je suis en train d'écrire une requête dynamique LINQ en utilisant la bibliothèque DynamicLibrary.cs du package NuGet.

avec LINQ régulière, la requête ressemble à quelque chose comme ça dans C#:

DocDBContext db = new DocDBContext(); 
var documents = db.Documents.Include(d => d.DocumentFilters); 
Guid gTest = Guid.Parse("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"); 

documents = documents.Where(d => d.DocumentFilters.Select(f => f.DocGUID).Contains(gTest)); 

Cela fonctionne parfaitement et récupère les documents délimités par le filtre GUID que je suis intéressé par Cependant, je dois placer cela. dans une chaîne de filtre dynamiquement, où il peut contenir d'autres filtres. Est-il possible de faire ça? J'ai essayé le code comme:

documents = documents.Where("DocumentFilters.Select(DocGUID).Contains(@0)", gTest); 

Erreur: Aucune méthode globale applicable 'Select' existe

ou

documents = documents.Where("[email protected]", gTest); 

Erreur: la propriété GUID n'existe pas sur DocumentFilters. (Ce qui est logique car DocumentFilters est une collection).

Je pensais aussi qu'il pourrait être utile de donner un coup de feu ce:

documents = documents.Where("DocumentFilters.AsQueryable().Select(DocGUID).Contains(@0)", gTest); 

Mais encore une fois, il ne ressemble pas à la bibliothèque prend en charge AsQueryable et lancers francs Erreur: Aucune méthode globale applicable « AsQueryable » existe .

Est-il possible d'écrire une telle restriction sur une propriété d'un objet énumérable dans la table Documents? Essayez d'utiliser Dynamic Linq, il peut être utilisé contre les chaînes.

Répondre

3

Donc, une solution a été de modifier Dynamic.cs en ajoutant "Select" à l'interface IEnumerableSignatures dans la classe ExpressionParser. Et d'ajouter en outre à la méthode ParseAggregate():

if (signature.Name == "Min" || signature.Name == "Max") 
     { 
      typeArgs = new Type[] { elementType, args[0].Type }; 
     } 
     else if (signature.Name == "Select") 
     { 
      typeArgs = new Type[] { elementType, Expression.Lambda(args[0], innerIt).Body.Type }; 
     } 

Cependant, après cela, je encore besoin de surcharger la méthode Contains() pour travailler avec GUIDs. Je n'ai pas pris la peine de le faire. Au lieu de cela j'ai réalisé que je peux simplement utiliser le .Any() déjà supporté au lieu de .Select()!

documents = documents.Where("DocumentFilters.Any(DocGUID.Equals(@0))", gTest); //!!! 

Je devais aussi changer le nom de la colonne de « GUID » à « DocGUID » parce que lors de l'écriture GUID.Equals() dans la chaîne de restriction, l'analyseur confondit pour le type GUID et non le nom de colonne, et a jeté l'erreur que Equals() n'est pas une extension valide pour le type GUID.

Désolé pour perdre tout le temps!

0

+0

J'essaie de l'utiliser. De toute façon j'ai déjà trouvé la solution. Merci! –