Last active
October 25, 2016 11:37
-
-
Save aanufriyev/62b7b4e42d0432c6c6fd25dd96155b89 to your computer and use it in GitHub Desktop.
Some expression stuff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace ConsoleApplication1 | |
{ | |
#region | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Linq.Expressions; | |
#endregion | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var products = new List<Product> | |
{ | |
new Product | |
{ | |
Category = new Category {Rating = 1}, | |
Seller = new Seller {Rating = 50} | |
} | |
}; | |
var predicate = PredicateBuilder.True<Product>(); | |
predicate = predicate.And(p => p.Category, Category.NiceRating); | |
predicate = predicate.And(p => p.Seller, Seller.GoodSeller); | |
var result = products.AsQueryable().Where(predicate); | |
} | |
} | |
public class Product | |
{ | |
public Category Category { get; set; } | |
public Seller Seller { get; set; } | |
} | |
public class Category : IHaveRating | |
{ | |
public static Expression<Func<IHaveRating, bool>> NiceRating { get; } = c => c.Rating >= 50; | |
public int Rating { get; set; } | |
public List<Product> Products { get; set; } | |
} | |
public class Seller : IHaveRating | |
{ | |
public static Expression<Func<IHaveRating, bool>> GoodSeller { get; } = s => s.Rating >= 4; | |
public int Rating { get; set; } | |
public List<Product> Products { get; set; } | |
} | |
public interface IHaveRating | |
{ | |
int Rating { get; set; } | |
} | |
public static class PredicateBuilder | |
{ | |
public static Expression<Func<T, bool>> True<T>() | |
{ | |
return f => true; | |
} | |
public static Expression<Func<T, bool>> False<T>() | |
{ | |
return f => false; | |
} | |
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, | |
Expression<Func<T, bool>> expr2) | |
{ | |
var invokedExpr = Expression.Invoke(expr2, expr1.Parameters); | |
return Expression.Lambda<Func<T, bool>> | |
(Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters); | |
} | |
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1, | |
Expression<Func<T, bool>> expr2) | |
{ | |
var invokedExpr = Expression.Invoke(expr2, expr1.Parameters); | |
return Expression.Lambda<Func<T, bool>> | |
(Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters); | |
} | |
public static Expression<Func<TIn, bool>> And<TIn, TInOut>(this Expression<Func<TIn, bool>> target, | |
Expression<Func<TIn, TInOut>> input, | |
Expression<Func<TInOut, bool>> inOutOut) | |
{ | |
var invoke = Expression.Invoke(input, target.Parameters); | |
var invokedExpr = Expression.Invoke(inOutOut, invoke); | |
return Expression.Lambda<Func<TIn, bool>>(Expression.AndAlso(target.Body, invokedExpr), target.Parameters); | |
} | |
public static Expression<Func<TIn, bool>> Or<TIn, TInOut>(this Expression<Func<TIn, bool>> target, | |
Expression<Func<TIn, TInOut>> input, | |
Expression<Func<TInOut, bool>> inOutOut) | |
{ | |
var invoke = Expression.Invoke(input, target.Parameters); | |
var invokedExpr = Expression.Invoke(inOutOut, invoke); | |
return Expression.Lambda<Func<TIn, bool>>(Expression.OrElse(target.Body, invokedExpr), target.Parameters); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment