我试图将股票Linq写入SQL查询等等,而且我发现我必须使用表达式而不是lambdas。
如果你不这样做,它会尝试将你的Linq直接转换为SQL,但它不起作用。
以表格上的主键为例。我们都被命名为不同的东西,但我想写一个标准的Linq WHERE子句,它使用一个表达式来选择正确的字段。
我写了以下测试代码:
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;
}
代码是主要工作,PKID过滤器(int)过滤器,我可以将其转换为通用代码,更多派生属性基于每个表返回表达式。
但这有点受限,我只想定义指向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.GreaterThan
Expression<Func<Beat, int>>
答案 0 :(得分:2)
我认为你必须通过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;
答案 1 :(得分:1)
站在Mehdi的肩膀上,我设法提出以下内容:
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是sql行类的linq。 您现在要做的就是覆盖PKName属性,所有PK表达式都使用通用的SELECT子句和连接。