2017-01-04 3 views
0

Bonjour J'ai des problèmes avec un arbre d'expression utilisant la méthode d'extension .Any().Linq Expression tree Any() issue

Voici mon code:

IQueryable<Book> querableBooks = Books.Values.AsQueryable<Book>(); 

ParameterExpression pe = Expression.Parameter(typeof(Book), "book"); 

MemberExpression props = Expression.Property(pe, "properties"); 

ParameterExpression propList = Expression.Parameter(typeof(List<BookProperty>), "properties"); 

var _test = Expression.Lambda<Func<List<BookProperty>, bool>>(operation, new ParameterExpression[] { propList }); 

var _Any = Expression.Call(typeof(Enumerable), "any", new Type[] { typeof(BookProperty) }, new Expression[] { propList }); 

Expression Lamba = Expression.Lambda(_Any, _props); 

_Test renvoie {propriétés => ((bookProperty.type.key == "lingerie") et (bookProperty.value == "1"))}

retours _any {properties.Any()}

retours Lambda

{book.properties => properties.Any()} La classe livre est comme ceci:

public class Book : IBook 
    { 

     public int id { get; set; } 
//Removed for clarity 
     public List<BookProperty> properties { get; set; } 

    } 

Une classe BookProperty:

public class BookProperty 
    { 
     public BookProperty() 
     { 
      value = "0"; 
     } 
     public int id { get; set; } 
     public int bookId { get; set; } 
     public Book book { get; set; } 
     public int typeId { get; set; } 
     public BookPropertyType type { get; set; } 
     public string value { get; set; } 
    } 

Et classe BookPropertyType:

public class BookPropertyType 
    { 
     public int id { get; set; } 
     public string groupe { get; set; } 
     public string key { get; set; } 
     public string label { get; set; } 
     public int order { get; set; } 
     public string editorType { get; set; } 
     public string unite { get; set; } 
    } 

Je suis proche, mais je ne sais pas comment fusionner correctement tout cela pour avoir un requête comme celle-ci

{book.propertie.Any (bookProperty => bookProperty.type.key == "lingerie") Et (bookProperty.value == "1")}

Merci pour votre aide.

+0

Il serait utile si vous incluez la 'Book' et Classes 'BookProperty'. –

+0

@IvanStoev J'ai ajouté les classes. Merci – Julien

+0

cherchez-vous à obtenir un sous-ensemble des livres interrogeables en fonction du type de propriété et de la valeur de la propriété? Si oui, qu'en est-il de: queryableBooks.Where (book => book.properties.Any (propriété => property.type.key == "lingerie" && property.value == "1")) – Brino

Répondre

2

Si je comprends bien, vous êtes à la recherche d'expression comme ceci:

Expression<Func<Book, bool>> bookPredicate = book => book.properties.Any(
    bookProperty => bookProperty.type.key == "lingerie" && bookProperty.value == "1"); 

Vous pouvez construire dynamiquement comme ceci:

var book = Expression.Parameter(typeof(Book), "book"); 
var properties = Expression.PropertyOrField(book, "properties"); 
var bookProperty = Expression.Parameter(typeof(BookProperty), "bookProperty"); 
// bookProperty.type.key == "lingerie" 
var conditionA = Expression.Equal(
    Expression.PropertyOrField(Expression.PropertyOrField(bookProperty, "type"), "key"), 
    Expression.Constant("lingerie") 
); 
// bookProperty.value == "1" 
var conditionB = Expression.Equal(
    Expression.PropertyOrField(bookProperty, "value"), 
    Expression.Constant("1") 
); 
// bookProperty.type.key == "lingerie" && bookProperty.value == "1" 
var condition = Expression.AndAlso(conditionA, conditionB); 
// bookProperty => bookProperty.type.key == "lingerie" && bookProperty.value == "1" 
var predicate = Expression.Lambda<Func<BookProperty, bool>>(condition, bookProperty); 
// book.properties.Any(bookProperty => bookProperty.type.key == "lingerie" && bookProperty.value == "1") 
var anyCall = Expression.Call(
    typeof(Enumerable), "Any", new[] { typeof(BookProperty) }, 
    properties, predicate 
); 
// book => book.properties.Any(...) 
var bookPredicate = Expression.Lambda<Func<Book, bool>>(anyCall, book); 
+0

Merci beaucoup pour votre aide. Cela fonctionne très bien. J'ai été capable de le mettre dans l'appel que j'ai déjà fait. Cela fonctionne parfaitement. Je vais nettoyer un peu mon code et poster le résultat final. – Julien