Linq 将Lambda表达式转换为表达式树

Linq 将Lambda表达式转换为表达式树,linq,reflection,lambda,tree,expression,Linq,Reflection,Lambda,Tree,Expression,我有兰姆达: var Ids = profileExample.CostCenters .Where(CostCentre => CostCentre != null) .Select(CostCentre => CostCentre.Id); 然后我转换到表达式树 static IEnumerable<Int64> AboveLambdaConvertedToExpressionTree(Profile profil

我有兰姆达:

var Ids = profileExample.CostCenters
           .Where(CostCentre => CostCentre != null)
           .Select(CostCentre => CostCentre.Id);
然后我转换到表达式树

    static IEnumerable<Int64> AboveLambdaConvertedToExpressionTree(Profile profileExample)
    {
        //Begin     var Ids = profileExample.CostCenters.Where(CostCentre => CostCentre != null).Select(CostCentre => CostCentre.Id);
        var property = profileExample.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => x.Name != "Id").First();
        var collection = ((IEnumerable)property.GetValue(profileExample, null)).AsQueryable();
        var collectionType = property.PropertyType.GetGenericArguments()[0];
        var collectionTypeName = collectionType.Name;

        var keyType = typeof(Int64);
        var keyName = "Id";

        //BeginWhere
        var parameter = Expression.Parameter(collectionType, collectionTypeName);

        var profileExampleWhere = Expression.Lambda(
                                            Expression.NotEqual(parameter, Expression.Constant(null)),
                                            parameter);

        var profileExampleWhereCall = Expression.Call(typeof(Enumerable),
                                                                "Where",
                                                                new Type[] { collectionType },
                                                                collection.Expression,
                                                                profileExampleWhere);
        //EndWhere

        //BeginSelect
        var profileExampleSelect = Expression.Lambda(Expression.PropertyOrField(parameter, keyName),
                                         parameter);

        var profileExampleSelectCall = Expression.Call(typeof(Enumerable),
                                                  "Select",
                                                  new Type[] { collectionType, keyType },
                                                  profileExampleWhereCall,
                                                  profileExampleSelect);



        var Ids = Expression.Lambda(profileExampleSelectCall).Compile().DynamicInvoke();
        //EndSelect
        //End     var Ids = profileExample.CostCenters.Where(CostCentre => CostCentre != null).Select(CostCentre => CostCentre.Id);

        return ((IEnumerable)Ids).Cast<Int64>();
    }
但是我陷入了
.Any(Id=>Ids.Contains(Id))…

        var id = Expression.Parameter(typeof(long), "Id");
        var costCentre = Expression.Parameter(typeof(CostCentre), "CostCentre");
        var profile = Expression.Parameter(typeof(Profile), "Profile");
        var selectLambda = Expression.Lambda(Expression.PropertyOrField(costCentre, "Id"), costCentre);
        var selectCall = Expression.Call(typeof(Enumerable),
                                 "Select",
                                 new Type[] { typeof(CostCentre), typeof(long) }, 
                                 Expression.PropertyOrField(profile, "CostCenters"),
                                 selectLambda);  
如何从selectCall和call ID中调用任何内容。包含


要作为控制台应用程序运行的完整代码如下:


使用系统;
使用系统集合;
使用System.Collections.Generic;
使用System.Linq;
使用System.Linq.Expressions;
运用系统反思;
命名空间表达式树
{
班级计划
{
静态void Main(字符串[]参数)
{
var Id=profileExample.CostCenters.Where(costcenter=>costcenter!=null)。选择(costcenter=>costcenter.Id);
Ids=以上LambdaConvertedToExpressionTree(配置文件示例);
var result=Set.AsQueryable().Where(Profile=>Profile.CostCenters.Select(costcenter=>costcenter.Id).Any(Id=>Id.Contains(Id)).ToList();
//表达式lambda=(Profile)=>Profile.CostCenters.Select(costcenter=>costcenter.Id).Any(Id=>Ids.Contains(Id));
var id=表达式参数(typeof(long),“id”);
var costcenter=表达式参数(typeof(costcenter),“costcenter”);
var profile=表达式参数(typeof(profile),“profile”);
var selectLambda=Expression.Lambda(Expression.PropertyOrField(costcenter,“Id”),costcenter);
var selectCall=Expression.Call(typeof(可枚举),
“选择”,
新类型[]{typeof(成本中心),typeof(长)},
Expression.PropertyOrField(配置文件,“成本中心”),
选择λ);
}
静态IEnumerable高于LambdaConvertedToExpressionTree(配置文件配置文件示例)
{
//我把它作为我需要做的例子
var-keyType=typeof(Int64);
var keyName=“Id”;
//开始变量Id=profileExample.CostCenters.Where(costcenter=>costcenter!=null)。选择(costcenter=>costcenter.Id);
var property=profileExample.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)。其中(x=>x.Name!=keyName)。First();
var collection=((IEnumerable)property.GetValue(profileExample,null)).AsQueryable();
var collectionType=property.PropertyType.GetGenericArguments()[0];
var collectionTypeName=collectionType.Name;
//从哪里开始
var parameter=Expression.parameter(collectionType,collectionTypeName);
var profileExampleWhere=Expression.Lambda(
Expression.NotEqual(参数,Expression.Constant(null)),
参数);
var profileExampleWhereCall=Expression.Call(类型(可枚举),
“哪里”,
新类型[]{collectionType},
收藏,表达,
profileExampleWhere);
//终点
//开始选择
var profileExampleSelect=Expression.Lambda(Expression.PropertyOrField(参数,键名),
参数);
var profileExampleSelectCall=Expression.Call(typeof(可枚举),
“选择”,
新类型[]{collectionType,keyType},
ProfileExampleWhere调用,
profileExampleSelect);
var id=Expression.Lambda(profileExampleSelectCall).Compile().DynamicInvoke();
//结束选择
//End var Id=profileExample.CostCenters.Where(costcenter=>costcenter!=null)。选择(costcenter=>costcenter.Id);
return((IEnumerable)id.Cast();
}
公共部分类配置文件
{
公共虚拟Int64 Id{get;set;}
公共虚拟ICollection成本中心{get;set;}
}
公共半类收费中心
{
公共虚拟Int64 Id{get;set;}
}
公共静态概要文件配置文件示例
{
得到
{
返回新配置文件()
{
Id=1,
CostCenters=new List(){new costcenter(){Id=2}}
};
}
}
公共静态IList集
{
得到
{
返回新列表(){new Profile(){Id=1,
CostCenters=new List(){new costcenter(){Id=1},
新建CostCentre(){Id=2}
},            
新配置文件(){Id=2,
CostCenters=new List(){new costcenter(){Id=2},
新建CostCentre(){Id=3}
},
新配置文件(){Id=3,
CostCenters=new List(){new costcenter(){Id=3}}
} };
}
}
}
}

由于Any是一种
通用方法,因此需要为特定类型创建它。下面的方法得到t
        var id = Expression.Parameter(typeof(long), "Id");
        var costCentre = Expression.Parameter(typeof(CostCentre), "CostCentre");
        var profile = Expression.Parameter(typeof(Profile), "Profile");
        var selectLambda = Expression.Lambda(Expression.PropertyOrField(costCentre, "Id"), costCentre);
        var selectCall = Expression.Call(typeof(Enumerable),
                                 "Select",
                                 new Type[] { typeof(CostCentre), typeof(long) }, 
                                 Expression.PropertyOrField(profile, "CostCenters"),
                                 selectLambda);  
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

namespace ExpressionTrees
{
    class Program
    {
        static void Main(string[] args)
        {
            var Ids = profileExample.CostCenters.Where(CostCentre => CostCentre != null).Select(CostCentre => CostCentre.Id);

            Ids = AboveLambdaConvertedToExpressionTree(profileExample);

            var result = Set.AsQueryable().Where(Profile => Profile.CostCenters.Select(CostCentre => CostCentre.Id).Any(Id => Ids.Contains(Id))).ToList();

            //Expression<Func<Profile, bool>> lambda = (Profile) => Profile.CostCenters.Select(CostCentre => CostCentre.Id).Any(Id => Ids.Contains(Id));

            var id = Expression.Parameter(typeof(long), "Id");
            var costCentre = Expression.Parameter(typeof(CostCentre), "CostCentre");
            var profile = Expression.Parameter(typeof(Profile), "Profile");
            var selectLambda = Expression.Lambda(Expression.PropertyOrField(costCentre, "Id"), costCentre);
            var selectCall = Expression.Call(typeof(Enumerable),
                                     "Select",
                                     new Type[] { typeof(CostCentre), typeof(long) }, 
                                     Expression.PropertyOrField(profile, "CostCenters"),
                                     selectLambda);                                   
        }

        static IEnumerable<Int64> AboveLambdaConvertedToExpressionTree(Profile profileExample)
        {
            // I show that as example of what i need to do
            var keyType = typeof(Int64);
            var keyName = "Id";

            //Begin     var Ids = profileExample.CostCenters.Where(CostCentre => CostCentre != null).Select(CostCentre => CostCentre.Id);
            var property = profileExample.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => x.Name != keyName).First();
            var collection = ((IEnumerable)property.GetValue(profileExample, null)).AsQueryable();
            var collectionType = property.PropertyType.GetGenericArguments()[0];
            var collectionTypeName = collectionType.Name;

            //BeginWhere
            var parameter = Expression.Parameter(collectionType, collectionTypeName);

            var profileExampleWhere = Expression.Lambda(
                                                Expression.NotEqual(parameter, Expression.Constant(null)),
                                                parameter);

            var profileExampleWhereCall = Expression.Call(typeof(Enumerable),
                                                                    "Where",
                                                                    new Type[] { collectionType },
                                                                    collection.Expression,
                                                                    profileExampleWhere);
            //EndWhere

            //BeginSelect
            var profileExampleSelect = Expression.Lambda(Expression.PropertyOrField(parameter, keyName),
                                             parameter);

            var profileExampleSelectCall = Expression.Call(typeof(Enumerable),
                                                      "Select",
                                                      new Type[] { collectionType, keyType },
                                                      profileExampleWhereCall,
                                                      profileExampleSelect);



            var Ids = Expression.Lambda(profileExampleSelectCall).Compile().DynamicInvoke();
            //EndSelect
            //End     var Ids = profileExample.CostCenters.Where(CostCentre => CostCentre != null).Select(CostCentre => CostCentre.Id);

            return ((IEnumerable)Ids).Cast<Int64>();
        }

        public partial class Profile
        {
            public virtual Int64 Id { get; set; }

            public virtual ICollection<CostCentre> CostCenters { get; set; }
        }


        public partial class CostCentre
        {
            public virtual Int64 Id { get; set; }
        }
        public static Profile profileExample
        {
            get
            {
                return new Profile()
                {
                    Id = 1,
                    CostCenters = new List<CostCentre>() { new CostCentre() { Id = 2 } }
                };
            }
        }

        public static IList<Profile> Set
        {
            get
            {
                return new List<Profile>() { new Profile() { Id = 1, 
                                                            CostCenters = new List<CostCentre>() {  new CostCentre() { Id = 1 }, 
                                                                                                    new CostCentre() { Id = 2 } } 
                                                          },            
                                            new Profile() { Id = 2, 
                                                            CostCenters = new List<CostCentre>() {  new CostCentre() { Id = 2 }, 
                                                                                                    new CostCentre() { Id = 3 } } 
                                            },
                                            new Profile() { Id = 3, 
                                                            CostCenters = new List<CostCentre>() {  new CostCentre() { Id = 3 } } 
                                            } };
            }
        }
    }
}
public static MethodInfo GetAnyExtensionMethod(Type forType)
{
    MethodInfo method = 
        typeof(Enumerable).GetMethods()
                          .First(m => m.Name.Equals("Any") && 
                                      m.GetParameters().Count() == 2);
    return method.MakeGenericMethod(new[] { forType });
}
class Program
{
    static void Main(string[] args)
    {
        //var Ids = profileExample.CostCenters.Where(CostCentre => CostCentre != null).Select(CostCentre => CostCentre.Id);

        var Ids = AboveLambdaConvertedToExpressionTree(profileExample);

        //var result = Set.AsQueryable().Where(Profile => Profile.CostCenters.Select(CostCentre => CostCentre.Id).Any(Id => Ids.Contains(Id))).ToList();

        var id = Expression.Parameter(typeof(long), "Id");
        var costCentre = Expression.Parameter(typeof(CostCentre), "CostCentre");
        var profile = Expression.Parameter(typeof(Profile), "Profile");
        var selectLambda = Expression.Lambda(Expression.PropertyOrField(costCentre, "Id"), costCentre);
        var selectCall = Expression.Call(typeof(Enumerable),
                                 "Select",
                                 new Type[] { typeof(CostCentre), typeof(long) }, 
                                 Expression.PropertyOrField(profile, "CostCenters"),
                                 selectLambda);                      

        //var id2 = Expression.Parameter(typeof(long), "Id");

        var containsCall = Expression.Call(typeof(Enumerable),
                              "Contains",
                              new Type[] { typeof(long) },
                              Expression.Constant(Ids),
                              id);

        var anyLambda = Expression.Lambda(containsCall, id);

        var anyCall = Expression.Call(typeof(Enumerable),
                     "Any",
                     new Type[] { typeof(long) },
                     selectCall,
                     anyLambda);

        var whereLambda = Expression.Lambda(anyCall, profile);

        var callExpression = Expression.Call(typeof(Queryable),
                                                    "Where",
                                                    new Type[] { typeof(Profile) },
                                                    Set.AsQueryable().Expression,
                                                    whereLambda);


        var result = Expression.Lambda(callExpression).Compile().DynamicInvoke();


    }