如何在C#中从另一个表达式创建一个表达式
本文关键字:表达式 创建 一个 另一个 | 更新日期: 2023-09-27 18:26:12
我正在尝试将stock Linq写入SQL查询等,我发现我必须使用表达式而不是lambdas。
如果你不这样做,它会尝试将你的Linq直接转换为SQL,但它不起作用。
以表上的主键为例。我们的名字都不一样,但我想写一个标准的LinqWHERE子句,它使用表达式来选择正确的字段。
我已经写了以下测试代码:
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;
}
代码是Main works,Filter(int)Filter by PKID,我可以将其转换为泛型代码,使用更多派生属性按表返回表达式。
但这有点有限,我只想定义指向PK字段的表达式,并在此基础上构建更多的库存表达式。
否则,如果我想要PKGreaterThan和PKEquals,我必须为每个表定义两次。我需要十几张桌子,还有几百张桌子。
只让每个表定义指向关键字段(PK、GUID、唯一字符串、创建日期-时间等)的表达式会更简洁
但我不知道怎么做。
到目前为止,我想出的最好的(它一点也不起作用)是:
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;
}
如何在Expression<Func<Beat, int>>
中包装Expression.GreaterThan
我认为您必须通过Expression.Lambda<Func<Beat, bool>>
将其转换为Lambda表达式
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;
站在迈赫迪的肩膀上,我成功地想出了以下东西:
class Program
{
static void Main(string[] args)
{
using (var ss = new DataScope(@"connString"))
{
var db = DataScope.DatabaseConnection;
var pk = 2;
var sql = db.Beats.AsQueryable();
sql = sql.Where(PKGreaterThan(pk));
var res = sql.ToList();
}
}
static string PKName { get { return "BeatID"; } }
static PropertyInfo PKProperty()
{
var output = typeof(Beat).GetProperties().Where(p => p.Name == PKName).SingleOrDefault();
return output;
}
static Expression<Func<Beat, bool>> PKGreaterThan(int pk)
{
var beatParameter = Expression.Parameter(typeof(Beat));
var beatPKProperty = Expression.Property(beatParameter, PKProperty());
var beatPKGreaterThanPK = Expression.GreaterThan(beatPKProperty, Expression.Constant(pk));
var output = Expression.Lambda<Func<Beat, bool>>(beatPKGreaterThanPK, beatParameter);
return output;
}
}
它现在位于一个泛型基类中,类型T是linq-to-sql行类。现在所要做的就是重写PKName属性,并且所有PK表达式都使用泛型SELECT子句和联接。