12
votes

Analyser la chaîne dans une requête LINQ

Quelle méthode serait considérée comme une meilleure pratique pour analyser une chaîne de Linq dans une requête?

ou en d'autres termes, quelle approche a le plus de sens de convertir: xxx > dans xxx

supposant que source fait référence à un iEnumerable <élément> ou iquéryable <élément> < / code> dans la portée locale.


3 commentaires

Malheureusement, cela va être difficile. J'espère que quelqu'un me surprend et me prouve tort, mais je ne m'attends pas à ce que cela se produise.


Ne répond pas exactement à votre question mais assez proche weblogs.asp.net/scottgu/archive/2008/01/07/...


On dirait que www.linqpad.net ferait ... mais je ne sais pas comment ils le font.


6 Réponses :


2
votes

Cela pourrait fonctionner pour vous: C # Eval équivalent?


0 commentaires

0
votes

Bien que cela ne donne pas spécifiquement d'exemple pour répondre à votre question, j'aurais pensé que la meilleure pratique serait généralement de construire un arbre d'expression de la chaîne.

in Cette question, j'ai demandé comment filtrer une requête LINQ avec une chaîne qui vous indique la construction d'une partie d'un arbre d'expression. Ce concept peut toutefois être étendu à la construction d'un arbre d'expression entier représentant votre chaîne.

Voir cet article de Microsoft .

Il y a probablement d'autres meilleurs messages là-bas. De plus, je pense que quelque chose comme Ravendb fait-il déjà dans sa base de code pour la définition d'index.


0 commentaires

5
votes

Cela nécessite une analyse de texte et une utilisation intensive de System.Linq .Expressions . J'ai fait du jouant avec ce ici et ici . Le code dans le deuxième article est quelque peu mis à jour à partir du premier mais toujours rude dans les angles. J'ai continué à vous gâter à cette occasion et à avoir une version quelque peu plus propre que je voulais poster si vous avez des intérêts. Je l'ai assez proche de soutenir un bon sous-ensemble d'ANSI SQL 89.


0 commentaires

3
votes

Vous allez avoir besoin d'un analyseur de langue C # (au moins v3.5, éventuellement v4.0, selon les fonctionnalités de la langue C # que vous souhaitez prendre en charge à Linq). Vous allez prendre ces résultats d'analyseurs et l'alimentez directement dans un arbre d'expression à l'aide d'un motif de visiteur. Je ne suis pas encore sûr mais je suis prêt à parier que vous aurez également besoin d'une forme d'analyse de type pour générer complètement les nœuds d'expression.

Je cherche la même chose que vous, mais je n'ai pas vraiment besoin de cela si mal que je n'ai pas cherché ni cher ni écrit de code le long de ces lignes.

J'ai écrit quelque chose qui prend une entrée de chaîne d'utilisateur et le compose à un assemblage dynamique à l'aide de la classe Microsoft.CSHARP.CSHARPCODPROVIDER Compiler fournisseur. Si vous voulez simplement prendre des chaînes de code et exécuter le résultat, cela devrait vous conviendra bien.

Voici la description de l'outil de console que j'ai écrit, Linqfilter:

http://bittwiddlers.org/?p=141

Voici le référentiel source. Linqfilter / Program.cs démontre comment utiliser le compilateur pour compiler l'expression LINQ:

http://bittwiddlers.org/viewsvn/trunk/public/linqfilter /? root = welldunne


3 commentaires

Une pensée se produit: Si vous étiez paranoïaque à propos de la chaîne devant être une expression, vous pouvez utiliser le csharpcodeprovider et générer du code le long des lignes de Expression > Query = (Linq Code ici); et ensuite vous aurez l'arborescence d'expression construite pour vous par le compilateur. C'est juste une question d'un compilé compile () pour récupérer un délégué pour l'exécuter et une réflexion pour vous trouver la méthode de l'Assemblée dynamique que vous avez générée afin que vous puissiez l'exécuter. J'espère que cela a du sens; Je suis une sorte de randonnée ici lol. :)


Pardonne-moi, il doit être un Expression >> ou expression >> . Dans votre code généré, vous pouvez concaténer en toute sécurité comme suit: expression >> getquery = () => (la requête LINQ ici); Le compilateur n'acceptera que des expressions valides qui peuvent être analysé dans un arbre d'expression. Pour C # v3.5, cela exclut les déclarations et les expressions d'affectation.


Pour exécuter la requête, prenez ce getquery et do getquery.compile () () . Les deux paires de parenthèses ne sont pas une erreur ici. Vous invoquez la méthode compile () qui vous donne un délégué et vous invoquez ce délégué qui vous renvoie votre iquéryable ou quel type iquéry / iEnumerable vous attendez de retour .



2
votes

Ceci peut vous aider ou ne pas vous aider, mais consultez Linq Dynamic Query Library .


0 commentaires

7
votes

commençant par .NET 4.6 Vous pouvez utiliser Csharpscript pour analyser Linq. En supposant que l'expression que vous souhaitez analyser est dans la variable de chaîne "Query", cela le fera:

string query = "from element in source where element.Property = ""param"" select element";
IEnumerable result = null;
try 
{
    var scriptOptions = ScriptOptions.Default.WithReferences(typeof(System.Linq.Enumerable).Assembly).WithImports("System.Linq");
    result = await CSharpScript.EvaluateAsync<IEnumerable>(
             query,
             scriptOptions,
             globals: global);
} catch (CompilationErrorException ex) {
//
}


2 commentaires

Toute façon de le faire dans le noyau .NET encore?


Je doute que ce sera aussi facile. Devinez que les csharpscript nécessaires et Linq ne font pas partie du noyau .NET. Certains uppotes seraient toujours gentils.