Question

J'essaie d'envelopper un code répétitif dans une méthode d'extension, pour nettoyer un peu les choses.

Le modèle que j'essaie d'éviter est de vérifier si une chaîne (normalement la valeur de texte d'un contrôle) est nul / vide, et si c'est le cas, la comparer en utilisant contient un champ dans mes données. De toute évidence, le champ n'est pas codé en dur dans mon extension, non plus le type d'objet.

Ce que j'ai fonctionne parfaitement dans linq sur des objets, mais j'obtiens l'erreur générique de l'exécution "Linq aux entités ne reconnaît pas la méthode" System.String invoke (genericQueryhelper.Customer) ', et cette méthode ne peut pas être traduite en une expression du magasin. " Lors de l'utilisation d'un modèle de cadre d'entité.

Voici ce que j'ai:

<System.Runtime.CompilerServices.Extension()>
Public Function CompareAndFilter(Of T)(source As System.Linq.IQueryable(Of T), expressionField As System.Linq.Expressions.Expression(Of System.Func(Of T, String)), compareTo As String)
    If String.IsNullOrEmpty(compareTo) Then
        Return source
    Else
        Dim compiledField As System.Func(Of T, String) = expressionField.Compile()
        Return source.Where(Function(x) compiledField.Invoke(x).Contains(compareTo))
    End If
End Function

Et j'ai aussi essayé:

<System.Runtime.CompilerServices.Extension()>
Public Function CompareAndFilter(Of T)(source As System.Linq.IQueryable(Of T), expressionField As System.Func(Of T, String), compareTo As String)
    If String.IsNullOrEmpty(compareTo) Then
        Return source
    Else
        Return source.Where(Function(x) expressionField.Invoke(x).Contains(compareTo))
    End If
End Function

Avec un résultat identique ...

Premièrement, est-ce même possible? Je veux que mon utilisation ressemble à ceci:

Dim results = repository.Customers.CompareAndFilter(Function(c) c.FirstName, searchText)

J'ai besoin de faire fonctionner cela contre une base de données SQL vraiment, car il filtre les résultats, donc je ne veux pas le faire en mémoire. Quelqu'un de pensées?

Était-ce utile?

La solution

Linq aux entités ne comprend pas comment invoquer un délégué, il a besoin d'une expression pour élaborer le SQL pour générer.

Ce qui suit pourrait être en mesure de faire ce que vous recherchez:

<System.Runtime.CompilerServices.Extension()>
Public Function CompareAndFilter(Of T)(source As System.Linq.IQueryable(Of T), expressionField As System.Linq.Expressions.Expression(Of System.Func(Of T, String)), compareTo As String)
    If String.IsNullOrEmpty(compareTo) Then
        Return source
    Else
        Return source.GroupBy(expressionField)
            .Where(Function(g) g.Key.Contains(compareTo))
            .SelectMany(Function(g) g)
    End If
End Function

GroupBy est utilisé pour sélectionner le champ spécifié par expressionField, alors la clé est vérifiée et les éléments de chaque groupe sont retournés.

Autres conseils

Oui, c'est possible, mais cela implique expression manipulation. Vous pouvez soit Analyser l'expression que vous avez donnée et construire la nouvelle expression de critère vous-même, ou avez Linqkit Effectuez une traversée d'arbre pour vous.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top