J'ai un site MVC qui utilise la grille de Kendo et j'essaie d'implémenter des filtres dynamiques. Les données que j'affiche contiennent plusieurs tables 1-à-plusieurs. Par exemple, j'ai une rangée de personnes, chaque personne peut avoir 0 ou plusieurs objets qui lui sont assignés. J'affichons une liste aplatie dans la grille:LINQ to Entities string based dynamic Où
Bob | Item 1, Item 2
Jane | Item 3
Si je devais coder en dur le filtre sur la colonne Items, il ressemblerait à ceci:
people.Where(p=> p.Items.Any(i=>i.name.contains("Item 1"))).ToList()
Je veux venir avec une façon générique de construire l'arbre d'expression afin que je puisse filtrer sur différents champs 1-à-plusieurs et effectuer des comparaisons différentes (par exemple, contains, startswith, equals, etc.). Idéalement, je voudrais avoir une méthode d'extension avec la syntaxe suivante:
public static IQueryable<TEntity> Where(this IQueryable<TEntity> source, string tableName, string fieldName, string comparisonOperator, string searchVal) where TEntity : class
alors je pourrais interroger sur plusieurs one-to-many tables:
if(searchOnItems)
persons = persons.Where("Items", "name", "Contains", "item 1);
if(searchOnOtherTableName)
persons = persons.Where("OtherTableName", "name", "Equals", "otherSearchValue);
persons.ToList();
Je tente d'utiliser LINQ to Entities string based dynamic OrderBy comme point de départ puisque le concept est similaire, mais je n'arrive pas à comprendre comment modifier la méthode GenerateSelector. Toutes les idées seraient grandement appréciées.
Édition - Mon code est sur un réseau fermé, je ferai de mon mieux pour reproduire ce que j'essaie. Voici le code que je tente de modifier. Le bloc de commentaire est où je suis coincé. Les exemples d'appel de la méthode d'extension "Where" ci-dessus sont toujours valides.
public static IQueryable<TEntity> Where<TEntity>(this IQueryable<TEntity> source, string tableName, string fieldName, string comparisonOperator, string searchVal) where TEntity : class
{
MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, "Where", tableName, fieldName, comparisonOperator, searchVal);
return source.Provider.CreateQuery<TEntity>(resultExp) as IOrderedQueryable<TEntity>;
}
private static MethodCallExpression GenerateMethodCall<TEntity>(IQueryable<TEntity> source, string methodName, string tableName, String fieldName, string comparisonOperator, string searchVal) where TEntity : class
{
Type type = typeof(TEntity);
Type selectorResultType;
LambdaExpression selector = GenerateSelector<TEntity>(tableName, fieldName, comparisonOperator, searchVal, out selectorResultType);
MethodCallExpression resultExp = Expression.Call(typeof(Queryable), methodName,
new Type[] { type, selectorResultType },
source.Expression, Expression.Quote(selector));
return resultExp;
}
private static LambdaExpression GenerateSelector<TEntity>(string tableName, String fieldName, string comparisonOperator, string searchVal, out Type resultType) where TEntity : class
{
// Create a parameter to pass into the Lambda expression (Entity => Entity.OrderByField).
var parameter = Expression.Parameter(typeof(TEntity), "Entity");
PropertyInfo property = typeof(TEntity).GetProperty(tableName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);;
Expression propertyAccess = Expression.MakeMemberAccess(parameter, property);;
/************************************************/
//property is now "TEntity.tableName"
//how do I go another step further so it becomes "TEntity.tableName.comparisonOperator(searchVal)"
/************************************************/
resultType = property.PropertyType;
// Create the order by expression.
return Expression.Lambda(propertyAccess, parameter);
}
Qu'en est-il en utilisant le (http://weblogs.asp.net/scottgu/dynamic-linq-part-1-using-the-linq-dynamic-query-library) [bibliothèque dynamique LINQ]? Vous devez vérifier la fonctionnalité qu'il fournit. Vous pouvez utiliser la bibliothèque DynamicQuery avec n'importe quel fournisseur de données LINQ (y compris LINQ to SQL, LINQ to Objects, LINQ to XML, LINQ to Entities, LINQ to SharePoint, LINQ to TerraServer, etc.). – Legends
Vous dites que votre problème est de faire fonctionner la méthode GenerateSelector, mais vous ne nous montrez pas le code avec lequel vous rencontrez un problème. Si vous avez un problème avec un code, vous devez nous montrer le code ou nous ne pouvons pas vous aider. – Hogan