I'm trying to write stock Linq to SQL queries and such and I've found I have to use expressions instead of lambdas.
If you don't, it tries to convert your Linq directly into SQL and it doesn't work.
Take an example of Primary Keys on a table. Ours are all named something different but I'd like to write a standard Linq WHERE clause which uses an expression to choose the correct field.
I have written the following test code:
static void Main(string[] args)
{
using (var ss = new DataScope()
{
var db = DataScope.DatabaseConnection;
var pk = 2;
var sql = db.Beats.AsQueryable();
sql = sql.Where(Filter(pk));
var res = sql.ToList();
}
}
static Expression<Func<Beat, bool>> Filter(int pk)
{
return e => e.BeatID > pk;
}
The code is Main works, Filter(int) filters by PKID and I can covert this to generic code, with more derived properties returning the expression on a per table basis.
But that's a bit limited, I'd like instead to only have to define the expression pointing at the PK field and build further stock expressions out of that.
Otherwise if I want PKGreaterThan and PKEquals, I have to define it twice for every table. And I need about a dozen, and there are hundreds of tables.
It would be much neater to just have each table define expressions pointing at key fields (PK, GUID, unique string, create date time, etc)
But I don't know how.
So far the best I've come up with (and it doesn't work in the slightest) is:
static Expression<Func<Beat, int>> PKExpression
{
get { return e => e.BeatID; }
}
static Expression<Func<Beat, bool>> SuperFilter(int pk)
{
var gt = Expression.GreaterThan(PKExpression, Expression.Constant(pk));
return e => gt;
}
How I wrap Expression.GreaterThan
in Expression<Func<Beat, int>>
I Think you must convert this to Lambda Expression by Expression.Lambda<Func<Beat, bool>>
ParameterExpression param = Expression.Parameter(typeof(Beat));
var gt = Expression.GreaterThan(Expression.Call(PKExpression,param), Expression.Constant(pk));
LambdaExpression condition =Expression.Lambda<Func<Beat, bool>>(gt, param);
return condition;