2012-01-16 3 views
4

Я построил пользовательский поставщик IQueryable. Поставщик преобразует запрос, напримерКак запросить коллекцию с Linq.Expressions

c.PurchaseDate == new DateTime(2011, 11, 29) && c.Name == "Elizabeth Brown" 

из основного кода в System.Linq.Expressions.Expression

Теперь мне нужно, чтобы запустить их против этой коллекции с Linq запрос

IQueryable<Customer> customers = _customers.AsQueryable(); 

Может кто-нибудь сказать мне, как запросить коллекцию с помощью Expression?

Благодаря

ответ

3
//Query = c.PurchaseDate == new DateTime(2011, 11, 29) && c.Name 
    // == "Elizabeth Brown") 
IQueryable<Customer> customers = _customers.AsQueryable<Customer>(); 

//Predicate parameter 
ParameterExpression parameter = Expression.Parameter(typeof(Customer), 
                  "customer"); 

//Create left expression 
Expression left = Expression.Property(parameter, typeof(Customer) 
            .GetProperty("PurchaseDate")); 
Expression right = Expression.Constant(new DateTime(2011, 11, 29)); 
Expression leftExp = Expression.Equal(left, right); 

//Create right expression tree 
left = Expression.Property(parameter, typeof(Customer).GetProperty("Name")); 
right = Expression.Constant("Elizabeth Brown", typeof(string)); 
Expression rightExp = Expression.Equal(left, right); 

//Combine the expressions into expression tree 
Expression expressionTree = Expression.AndAlso(leftExp, rightExp); 

//Create an expression tree that represents the expression 
MethodCallExpression methodCall = Expression.Call(
    typeof(Queryable), 
    "Where", 
    new Type[] { customers.ElementType }, 
    customers.Expression, 
    Expression 
       .Lambda<Func<Customer, bool>> 
       (expressionTree, new ParameterExpression[] { parameter })); 

// Create an executable query from the expression tree. 
IQueryable<Customer> results = 
       customers.Provider.CreateQuery<Customer>(methodCall); 

// Enumerate the results 
foreach (Customer customer in results) 
{ 
    Console.WriteLine("{0} {1}", customer.Name, customer.PurchaseDate); 
} 

Console.ReadLine(); 

Я закончил с задачей таким образом. IQueryable - действительно замечательный материал. Наслаждайтесь!

+0

Wow! Это впечатляет! Строка 'Expression left = Expression.Property (pe, typeof (Customer)' должна иметь 'параметр' вместо' pe' правильно? – gideon

+0

На самом деле в вашем реальном коде вам нужно переопределить абстрактный класс ExpressionVisitor для посещения и выдавить эти значения в runtime, но для демонстрации я создал эти три значения Expression в статическом контексте. – user1135594

+0

Да, вы правы. Я ошибся в подготовке образца, но теперь исправлен. Этот код представляет только базовые функции, просто чтобы понять, как работает этот метод. Чтобы продемонстрировать, что я создал как левое, так и правое выражение предложения lambda, соответствующее c.PurchaseDate == new DateTime (2011, 11, 29) && c.Name == "Elizabeth Brown" Параметр ParameterExpression определяет только тип и параметр c. – user1135594

Смежные вопросы