J'utilise la bibliothèque Dynamic Linq (System.Linq.Dynamic) de Microsoft pour générer des requêtes au moment de l'exécution. Cela a très bien fonctionné pour moi, mais pour un scénario spécifique.
Scénario simplifié - J'essaie d'interroger toutes les revendications qui ont des balises spécifiques que l'utilisateur a sélectionnées et dont le solde est supérieur à un certain nombre.
static void Main(string[] args)
{
var claims = new List<Claim>();
claims.Add(new Claim { Balance = 100, Tags = new List<string> { "Blah", "Blah Blah" } });
claims.Add(new Claim { Balance = 500, Tags = new List<string> { "Dummy Tag", "Dummy tag 1" } });
// tags to be searched for
var tags = new List<string> { "New", "Blah" };
var parameters = new List<object>();
parameters.Add(tags);
var query = claims.AsQueryable().Where("Tags.Any(@0.Contains(outerIt)) AND Balance > 100", parameters.ToArray());
}
public class Claim
{
public decimal? Balance { get; set; }
public List<string> Tags { get; set; }
}
Cette requête génère une erreur:
Une exception non gérée du type 'System.Linq.Dynamic.ParseException' s'est produite dans System.Linq.Dynamic.dll Informations supplémentaires: Aucune propriété ou champ 'Balance' n'existe dans le type 'String'
L'analyseur dynamique linq semble essayer de trouver la propriété Balance sur le tag et non sur l'objet Claim.
Il se peut que je manque quelque chose ou cela pourrait être un bogue dans la bibliothèque.
J'apprécierais vraiment si quelqu'un pouvait m'aider avec ça.
Trouvé un / bug dans ParseAggregate ... La poussée de it
â † » outerIt
et ne fonctionne pas si retour il y a plusieurs niveaux. Le code suppose que le it
et le outerIt
ne seront pas modifiés par un tiers avant d'être réinitialisés (techniquement, le code n'est pas réentrant). Vous pouvez essayer avec d'autres variantes de System.Linq.Dynamic
(il y en a comme deux ou trois variantes). Certaines variantes l'ont probablement déjà corrigé.
Ou vous pouvez prendre le code du site lié et le recompiler dans votre code (à la fin le System.Linq.Dynamic "original" est un seul fichier cs) et vous pouvez le patcher comme ceci:
Expression ParseAggregate(Expression instance, Type elementType, string methodName, int errorPos)
{
// Change starts here
var originalIt = it;
var originalOuterIt = outerIt;
// Change ends here
outerIt = it;
ParameterExpression innerIt = Expression.Parameter(elementType, elementType.Name);
it = innerIt;
Expression[] args = ParseArgumentList();
// Change starts here
it = originalIt;
outerIt = originalOuterIt;
// Change ends here
MethodBase signature;
if (FindMethod(typeof(IEnumerableSignatures), methodName, false, args, out signature) != 1)
J'ai déjà ouvert un problème avec la correction de bogue suggérée dans le github du projet.
Cela semble fonctionner correctement dans ma version: System.Linq.Dynamic.Core
Voir le test ici: https://github.com/StefH/System.Linq.Dynamic.Core/blob/master/test/System.Linq.Dynamic.Core.Tests/ComplexTests.cs#L19