Reputation: 9698
I have an entity class like
public class BookPage {
public int PageIndex { get; set; }
}
then I have an expression:
Expression<Func<int, bool>> pageIndexCondition = idx => idx == 1;
and the expression I want:
Expression<Func<BookPage, bool>> pageCondition = bookPage => bookPage.PageIndex == 1;
The question: How do I use pageIndexCondition
to do LINQ-to-SQL query, or how can I convert pageIndexCondition
into pageCondition
?
Edit: Another solution that would be less elegant, but still meet my requirement is:
Expression<Func<T, bool>> GetPageIndexCondition(Expression<Func<T, int>> selector) {
return (T item) => selector(item) < 10; // This won't work because selector is Expression, so how to implement this correctly?
}
...
var pageCondition = GetPageIndexCondition(page => page.PageIndex);
Upvotes: 2
Views: 180
Reputation: 14350
I like doing these things, though as others have said, there's probably more efficient and better ways to do it:
void Main()
{
Expression<Func<int, bool>> pageIndexCondition = idx => idx == 1;
Expression<Func<BookPage, bool>> converted = ExpressionConverter.Convert(pageIndexCondition);
}
public class ExpressionConverter : ExpressionVisitor
{
public static Expression<Func<BookPage, bool>> Convert(Expression<Func<int, bool>> e)
{
var oldParameter = e.Parameters.First();
var newParameter = Expression.Parameter(typeof(BookPage), "bp");
Expression<Func<BookPage, int>> x = (BookPage bp) => bp.PageIndex;
var property = ((x.Body as MemberExpression).Member as PropertyInfo);
var memberAccess = Expression.Property(newParameter, property);
var converter = new ExpressionConverter(oldParameter, memberAccess);
return (Expression<Func<BookPage, bool>>)Expression.Lambda(converter.Visit(e.Body), newParameter);
}
private ParameterExpression pe;
private Expression replacement;
public ExpressionConverter(ParameterExpression pe, Expression replacement)
{
this.pe = pe;
this.replacement = replacement;
}
protected override Expression VisitParameter(ParameterExpression node)
{
if(node == pe)
return replacement;
return base.VisitParameter(node);
}
}
Upvotes: 1
Reputation: 12956
var pages = new List<BookPage>
{
new BookPage { PageIndex = 1 },
new BookPage { PageIndex = 2 }
};
Expression<Func<BookPage, bool>> pageCondition = bookPage => bookPage.PageIndex == 1;
BookPage result = pages.AsQueryable().Single(pageCondition);
If you want a generic select by id you will have to do something like;
public virtual IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null)
{
if (filter != null)
{
query = query.Where(filter);
}
}
This goes in your generic repository.
Upvotes: 0