标签: expression-trees

如何使用方法调用生成已编译的lambda?

我在运行时为给定的成员生成编译的getter方法.现在,我的代码只是假设getter方法的结果是一个字符串(适用于测试).但是,我想用我编写的自定义转换器类来完成这项工作,请参阅下面的"ConverterBase"参考,我已经添加了.

我无法弄清楚如何将转换器类的调用添加到我的表达式树.

    public Func<U, string> GetGetter<U>(MemberInfo info)
    {
        Type t = null;
        if (info is PropertyInfo) 
        {
            t = ((PropertyInfo)info).PropertyType;
        }
        else if (info is FieldInfo)
        {
            t = ((FieldInfo)info).FieldType;
        }
        else
        {
            throw new Exception("Unknown member type");
        }

        //TODO, replace with ability to specify in custom attribute
        ConverterBase typeConverter = new ConverterBase();

        ParameterExpression target = Expression.Parameter(typeof(U), "target");
        MemberExpression memberAccess = Expression.MakeMemberAccess(target, info);

        //TODO here, make the expression call "typeConverter.FieldToString(fieldValue)"

        LambdaExpression getter = Expression.Lambda(memberAccess, target);

        return (Func<U, string>)getter.Compile();
    }
Run Code Online (Sandbox Code Playgroud)

我正在寻找第二个TODO区域的内容(我可以处理第一个:)). …

c# lambda expression-trees

1
推荐指数
1
解决办法
1503
查看次数

C# 表达式语法

我正在考虑Expression<Func<>>和 之间的区别Func<>,想知道是否可以将静态方法转换为表达式树,如下所示:

class Program
{
    static void Main(string[] args)
    {
        Func<int, int> t = x => hrm(x);
        Func<int, int> t2 = new Func<int, int>(hrm);

        // Works as expected:
        Expression<Func<int, int>> et = x => hrm(x);
        // Brokenness:
        Expression<Func<int, int>> et2 = new Func<int, int>(hrm);
    }

    static int hrm(int x)
    {
        return x + 9;
    }
}
Run Code Online (Sandbox Code Playgroud)

第二个“Func<>”有何特别之处,以至于它无法转换为表达式,而第一个“Func<>”可以转换为表达式?

c# expression-trees

1
推荐指数
1
解决办法
1263
查看次数

C# 遍历表达式树提取表名

我需要一种方法来遍历 LINQ-to-SQL 表达式树以提取查询中的表名称。即使只是查询中使用的第一个表可能就足够了。

例子:

var query = from c in Db.Customers select c;
Run Code Online (Sandbox Code Playgroud)

以及理想的函数:

string TableName = ExtractTablesFromQuery(query);
Run Code Online (Sandbox Code Playgroud)

将返回字符串“Customers”

expression-trees linq-to-sql

1
推荐指数
1
解决办法
1269
查看次数

如何反映T为查询构建表达式树?

我正在尝试构建一个通用类来处理来自EF的实体.这个类与存储库进行对话,但是这个类创建了发送到存储库的表达式.无论如何,我只是想实现一个虚拟方法,它将作为常见查询的基础.具体来说,它将接受一个an int,它只需要对相关实体的主键执行查询.

我一直在搞砸它,我已经建立了一个可能或可能不起作用的反射.我这样说是因为我得到一条NotSupportedException带有LINQ to Entities的消息,无法识别方法'System.Object GetValue(System.Object,System.Object [])'方法,并且此方法无法转换为商店表达式.所以然后我尝试了另一种方法,它产生了相同的异常,但LINQ表达式错误的节点类型'ArrayIndex'在LINQ to Entities中不受支持.我知道这是因为EF不会像L2S那样解析表达式.

无论如何,我正在跳跃一个有更多经验的人可以指出我正确的方向.我正在用我所做的两次尝试发布整个班级.

public class Provider<T> where T : class {
    protected readonly Repository<T> Repository = null;

    private readonly string TEntityName = typeof(T).Name;

    [Inject]
    public Provider(
        Repository<T> Repository) {
        this.Repository = Repository;
    }

    public virtual void Add(
        T TEntity) {
        this.Repository.Insert(TEntity);
    }

    public virtual T Get(
        int PrimaryKey) {
        //  The LINQ expression node type 'ArrayIndex' is not supported in
        //  LINQ …
Run Code Online (Sandbox Code Playgroud)

c# linq reflection entity-framework expression-trees

1
推荐指数
1
解决办法
3263
查看次数

何时使用Expression

我想确定要使用什么......

我需要IEnumerable<TSource>将一个函数传递给将实体成员的值写入文件的函数.这是IEnumerable的样子:

var persons = new[] {
    new Person {
        RecordID = 0,
        PersonFName = "Joe",
        PersonMName = "",
        PersonLName = "Smith",
        PersonZip="75227"
    }, 
    new Person {
        RecordID = 1,
        PersonFName = "Mary",
        PersonMName = "Hada",
        PersonLName = "Lamb",
        PersonZip="75217"
    }};
Run Code Online (Sandbox Code Playgroud)

将IEnumerable传递给读取每个实体的函数以便读取每个字段值的最佳方法是什么?

我以为我会用以下东西:

void WriteData<TSource>(Expression<IEnumerable<Person>> expression)
{
    // do stuff
}
Run Code Online (Sandbox Code Playgroud)

我无法找到解释如何确定何时应该使用Expression而不仅仅是传递IEnumerable的资源.然后,我如何创建反映的表达式persons

理想情况下,似乎我会像这样调用WriteData:

WriteData(persons); 
Run Code Online (Sandbox Code Playgroud)

我是否朝着正确的方向前进?

c# .net-4.0 expression-trees

1
推荐指数
1
解决办法
108
查看次数

用于打印表达式的库

我正在寻找提供表达式打印功能的库(从 lambda 转换为表达式树)。换句话说,它应该做与这里解析示例类似的工作,但显然应该更完整。有人知道这样的图书馆吗?

c# expression-trees

1
推荐指数
1
解决办法
2094
查看次数

使用对象类型的参数调用 Func&lt;&gt;

我有(例如) a ,Func<int, int>我想像往常一样调用它,除了参数的类型为objectratingr than int。我只知道 Func 的确切类型和运行时的参数,因为 Func 是使用表达式树创建的,现在可以从变量访问dynamic。(简化)代码示例:

using System.Linq.Expressions;

namespace FuncExample
{
    class Program
    {
        static void Main(string[] args)
        {
            object myFunc = CreateFunc(); // Could return something like
                                          // Func<int, int>, but may return a
                                          // completely different Func<> depending on
                                          // arguments etc.
            object result = getFromFunc(5, myFunc);
        }

        public static object CreateFunc()
        {
            LambdaExpression expr = Expression.Lambda(
                /*
                 * Create an expression
                 */
                );
            return expr.Compile();
        } …
Run Code Online (Sandbox Code Playgroud)

c# func expression-trees

1
推荐指数
1
解决办法
3633
查看次数

如何使用表达式树构建匿名对象

我上课了

public class SomeClass
{
    public int num { get; set; }
    public string str{ get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我需要构造一个lambda表达式,如:(x => new {new_num = x.num,new_str = x.str})

属性列在一些可枚举对象中(这很重要).让我们说吧List<KeyValuePair<string, string>>

我的代码是:

// Test properties list
var listOfParams = new List<KeyValuePair<string, string>>();
listOfParams.Add(new KeyValuePair<string, string>("new_num","num"));
listOfParams.Add(new KeyValuePair<string, string>("new_str","str"));

// SomeClass as particular test case
var tModelType = typeof(SomeClass); 

ParameterExpression pe = Expression.Parameter(tModelType, "m");
NewExpression ne = Expression.New(typeof(object)); //<-- trying to emulate `new object{}`

List<Expression> lInit = new List<Expression>(); 

PropertyInfo pi; …
Run Code Online (Sandbox Code Playgroud)

c# reflection dynamic anonymous-types expression-trees

1
推荐指数
1
解决办法
580
查看次数

如何在不转换C#中的Expression.Convert的情况下获取Nullable值(字段)的表达式?

我在形成动态查询表达式期间处理Nullable类型的scanario.这些表达式将从任何SQL表中获取过滤数据(使用EF与Code First类连接).

我有正常的对象(例如,托运操作几个属性以及Nullable属性).

我的表达形式很顺利,直到我遇到一些Nullable类型.在这些无用之处,我得到了

没有为类型'System.Nullable`1 [System.Single]'和'System.Single'定义二元运算符NotEqual.

为了删除此异常,我正在使用关于在不同线程上发布的转换的所有appraoches.

在Expression树中调用lambda表达式

尝试使用表达式树过滤Nullable类型

这些都是生成带有"Convert"字样的表达式(即Convert(someValue)),结果我总是有表达式

t=>(t.Consignment.Id = 45000 && t.Consignment.someProperty>=45 Or t.Consignment.Weight! = Convert(5000)).
Run Code Online (Sandbox Code Playgroud)

当然我需要整个上面的表达式没有"转换".因为这个"转换"不会相应地从表中获取数据.

任何帮助将不胜感激!还应该做什么?我已经知道转换,但是这使得整个表达式无用,因为它不会因为不必要的"转换"而投影记录

添加

   Expression NotEqual<T>(Expression PropertyType, ConstantExpression a_Constant, ParameterExpression parameter)
   {
    if(IsNullableType(Property.Type) &&!IsNullableType(a_Constant.Type))
    {
      var converted = a_Constant.Type != Property.Type ?  (Expression)Expression.Convert(a_Constant, Property.Type): (Expression)a_Constant;

     // here above statement returns (Convert(50000)) and all I want (50000), but i tried all combinitions from Expression in order to form this constant as expression, it always throws exception what I mentioned originally.

     var body = …
Run Code Online (Sandbox Code Playgroud)

c# lambda expression-trees linq-expressions

1
推荐指数
1
解决办法
3334
查看次数

如何为多级属性/子属性构建表达式树

我有以下字符串表达式定义对象遍历"eBnum".其中e定义了我的字符串表达式中的根实体

 class BTest
 {      
    public int num{get:set;}
 }

 class Test
 {
     public int sample {get; set;}
     public BTest B {get; set;} 
 }

 static void TestProperty()
 {
    Test obj = new Test();
    obj.sample = 40;
    obj.B = new BTest(){ num=5}

    Expression propertyExpr = Expression.Property(Expression.Constant(obj),"num");

    Console.WriteLine(Expression.Lambda<Func<int>>(propertyExpr).Compile()());
Run Code Online (Sandbox Code Playgroud)

}

在下面的语句Expression.Property(Expression.Constant(obj),"num"); 我能够获得第一级属性"sample"的值,但不能获得第二级属性的值?

我在这里错过了什么吗?我试图基于"num"属性值构建一个二进制表达式.

c# expression expression-trees

1
推荐指数
1
解决办法
1017
查看次数