Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从C#中的另一个表达式创建表达式?_C#_Sql_Sql Server_Linq_Linq Expressions - Fatal编程技术网

如何从C#中的另一个表达式创建表达式?

如何从C#中的另一个表达式创建表达式?,c#,sql,sql-server,linq,linq-expressions,C#,Sql,Sql Server,Linq,Linq Expressions,我正在尝试将股票Linq写入SQL查询等等,我发现我必须使用表达式而不是lambdas 如果您不这样做,它会尝试将Linq直接转换为SQL,但它不起作用 以表上的主键为例。我们的名字都不一样,但我想写一个标准的Linq WHERE子句,它使用一个表达式来选择正确的字段 我编写了以下测试代码: static void Main(string[] args) { using (var ss = new DataScope() {

我正在尝试将股票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;
    }
static void Main(字符串[]args)
{
使用(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();
}
}
静态表达式筛选器(int-pk)
{
返回e=>e.BeatID>pk;
}
这段代码是主要的工作,通过PKID过滤(int),我可以将其转换为通用代码,使用更多的派生属性在每个表的基础上返回表达式

但这有点有限,我只想定义指向PK字段的表达式,并从中构建更多的库存表达式

否则,如果我想要PKGreaterThan和PKEquals,我必须为每个表定义两次。 我需要一打,还有几百张桌子

让每个表定义指向关键字段(PK、GUID、唯一字符串、创建日期时间等)的表达式会更整洁

但我不知道怎么做

到目前为止,我想到的最好的办法(但一点也不管用)是:

静态表达式PKExpression
{
获取{returne e=>e.BeatID;}
}
静态表达式超过滤器(int-pk)
{
var gt=表达式大于(PKExpression,表达式常数(pk));
返回e=>gt;
}

如何在
表达式中包装
表达式。大于
我认为您必须通过
表达式将其转换为Lambda表达式。Lambda

ParameterExpression param=Expression.Parameter(typeof(Beat));
var gt=Expression.GreaterThan(Expression.Call(PKExpression,param),Expression.Constant(pk));
LambdaExpression条件=表达式.Lambda(gt,param);
返回条件;

站在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;
    }
}
类程序
{
静态void Main(字符串[]参数)
{
使用(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();
}
}
静态字符串PKName{get{返回“BeatID”;}
静态属性info PKProperty()
{
var output=typeof(Beat).GetProperties(),其中(p=>p.Name==PKName).SingleOrDefault();
返回输出;
}
静态表达式PKGreaterThan(int-pk)
{
var beatParameter=表达式参数(typeof(Beat));
var beatPKProperty=Expression.Property(beatParameter,PKProperty());
var beatPKGreaterThanPK=Expression.GreaterThan(beatPKProperty,Expression.Constant(pk));
var output=Expression.Lambda(beatPKGreaterThanPK,beatParameter);
返回输出;
}
}
它现在位于一个通用基类中,类型T是linq to sql行类。
您现在所要做的就是重写PKName属性,所有的PK表达式都可以使用泛型SELECT子句和连接。

这是我问题的答案,但它仍然不起作用。我犯了进一步的错误,我得到了错误:
没有为type'System.Func``2[Beat,Int32]定义大于的二进制运算符'和'Int32'。
。此外,在更大的上下文中,您需要用
LamdaExpression
或(我的首选)
var
替换
LambdaExpression
。但是在expression.call中,您必须使用
class.GetType().GetMehtod(“PKExpression”)获取方法
另外,我认为PKExpression的类型有误。它必须是指向Beat属性(在本例中为BeatID)的表达式。
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;
    }
}