Non-static Expression<Func<X>> with access to 'this'
c#, expression-trees, lambda, linq, linq-to-sql
Solution
partial class Item
{
public static Expression<Func<Item, bool>> IsSpecial = (i => Math.Sqrt(i.Id)%2==0);
}
Suggestion: add the `readonly` keyword.
Then I can use that property in a linq-to-sql query like this:
datacontext.Item.Where(Item.IsSpecial)
Right, because `Where` accepts a parameter of type `Expression<Func<Item, bool>>`, which `Item.IsSpecial` is.
Now for aesthetic reasons, I want to make IsSpecial nonstatic and modify it so I can call it like this:
datacontext.Item.Where(i => i.IsSpecial())
The reason this doesn't work is because `IsSpecial` isn't a function, it's an expression tree. `()` can only be applied to functions. An expression tree describes a function, but isn't one. You can create a real function using `expression.Compile()`:
datacontext.Item.Where(i => (IsSpecial.Compile()) (i))
However, this won't work, because again, `Where` is passed an expression tree, and `IsSpecial.Compile()` isn't actually called. LINQ to SQL tries to convert it to SQL, fails because it doesn't recognise `Expression.Compile`, and throws an exception.
However, if you could replace `(IsSpecial.Compile())` before LINQ to SQL were to see it...
That's where LINQKit comes in:
It provides just that bit of expression tree manipulation to get it working.
datacontext.Item.AsExpandable().Where(i => (IsSpecial.Compile()) (i))
The `.AsExpandable()` creates a wrapper around `datacontext.Item` to pre-filter the expression.
Ideally this would also allow combining of statements, which the above (working) snytax does not allow:
datacontext.Item.Where(i => i.IsSpecial() && i.Id >100)
No problem:
datacontext.Item.AsExpandable().Where(i => (IsSpecial.Compile()) (i) && i.Id > 100)
Problem
I have a database table `Item` and access it with linq-to-sql. I can define a custom Method IsSpecial() for Items which returns true if the square root of Item.id is even: ``` partial class Item { public static Expression<Func<Item, bool>> IsSpecial = (i => Math.Sqrt(i.Id)%2==0); } ``` Then I can use that property in a linq-to-sql query like this: ``` datacontext.Item.Where(Item.IsSpecial) ``` Now for aesthetic reasons, I want to make IsSpecial nonstatic and modify it so I can call it like this: ``` datacontext.Item.Where(i => i.IsSpecial()) ``` Ideally this would also allow combining of statements, which the above (working) snytax does not allow: ``` datacontext.Item.Where(i => i.IsSpecial() && i.Id >100) ``` What is the correct syntax for defining this method? This does not work: ``` partial class Item { public Expression<Func<bool>> IsSpecial = ( () => Math.Sqrt(this.Id)%2==0 ); // 'this' keyword not available in current context } ``` edit: I am beginning to suspect that I am asking for something that the syntax simply does not allow I guess I can live with `datacontext.Item.Where(Item.IsSpecial).Where(i => i>100)`