.net Lambda到表达式

.net Lambda到表达式,.net,linq,lambda,closures,expression,.net,Linq,Lambda,Closures,Expression,如何生成这个lambda () => SomeObj.SomeProp 使用Expression.MakeMemberAccess和此类方法。我知道如何生成SomeObj=>SomeObj.SomeProp,但问题是()部分。这以某种方式转换为DisplayClass 谢谢 这是调用UvediSortiranje方法的联接。如果我使用inestead UvediSortiranje(“Naziv”)方法.OrderBy(()=>pfA.Naziv),一切都可以 Firma fA = nu

如何生成这个lambda

() => SomeObj.SomeProp
使用Expression.MakeMemberAccess和此类方法。我知道如何生成SomeObj=>SomeObj.SomeProp,但问题是()部分。这以某种方式转换为DisplayClass

谢谢

这是调用UvediSortiranje方法的联接。如果我使用inestead UvediSortiranje(“Naziv”)方法.OrderBy(()=>pfA.Naziv),一切都可以

Firma fA = null;
PrevodFirme pfA = null;
Jezik jA = null;

return this.Sesija.QueryOver<Firma>(() => fA)
            .UvediSortiranje(sortirajPo, fA) //!!!!
            .Left.JoinAlias(() => fA.Prevodi, () => pfA)
            .UvediSortiranje(sortirajPo, pfA) //!!!!
            .Left.JoinAlias(() => pfA.Jezik, () => jA)
            .UvediSortiranje(sortirajPo, jA) //!!!!
            .Where(Restrictions.Disjunction().Add(Restrictions.On(() => pfA.Id).IsIn(pfr)).Add(Restrictions.On(() => jA.Id).IsIn(jr)))
            .Where(() => jA.Id == jezikId)
            .Skip(odZapisa)
            .Take(brojZapisa)
            .List();
Firma fA=null;
PrevodFirme pfA=null;
Jezik-jA=null;
返回这个.Sesija.QueryOver(()=>fA)
.UvediSortiranje(sortirajPo,fA)/!!!!
.Left.JoinAlias(()=>fA.Prevodi,()=>pfA)
.UvediSortiranje(sortirajPo,pfA)/!!!!
.Left.JoinAlias(()=>pfA.Jezik,()=>jA)
.UvediSortiranje(佐治亚州索提拉波)/!!!!
.Where(Restrictions.Disjunction().Add(Restrictions.On(()=>pfA.Id).IsIn(pfr)).Add(Restrictions.On(()=>jA.Id).IsIn(jr)))
.Where(()=>jA.Id==jezikId)
.Skip(奥扎皮萨)
.拿(布罗扎皮萨)
.List();
另一种方法是延拓法:

public static class Ekst
{
   public static IQueryOver<TRoot, TSubType> UvediSortiranje<TRoot, TSubType, T>(this IQueryOver<TRoot, TSubType> ovo, string sortirajPo, T klasa) where T : class 
    {
        //provjeri da li sortiraj po zadovoljava konvenciju Objekat.Svojstvo i ako da, splituj ga na to
        var niz = sortirajPo.Split('.');
        // provjeri da li postoje ova svojstva u ovom objektu i da li se poklapaju imena

        if (niz.Length <= 0) return ovo;

        if (/*typeof(TSubType).Name == niz[0]*/ typeof(T).Name == niz[0])
        {
            //var arg = Expression.Constant(null, typeof(TSubType));
            //var body = Expression.Convert(Expression.PropertyOrField(arg, niz[1]),
            //    typeof(object));
            //var lambda = Expression.Lambda<Func<object>>(body);


            var param = Expression.Constant(klasa, typeof(T));
            var key = typeof(T).GetMember(niz[1]).First();
            //var rhs = Expression.MakeMemberAccess(Expression.Constant(itemToCompare), key);
            var lhs = Expression.MakeMemberAccess(param, key);
            //var body = Expression.Equal(lhs, rhs);

            var lambda = Expression.Lambda<Func<object>>(
            MemberExpression.MakeMemberAccess(param, key)
        );

            //lambda = (() => Expression.PropertyOrField(arg, niz[1]));

            return niz[2].ToLower() == "asc" ? ovo.OrderBy(lambda).Asc : ovo.OrderBy(lambda).Desc;
        }
        //u suprotnom vrcemo ovo bez ikakvog sortiranja
        return ovo;
    }
}
公共静态类Ekst
{
公共静态IQueryOver UvediSortiranje(此IQueryOver ovo,字符串sortirajPo,T klasa),其中T:class
{
//证明扎多伏尔爪哇的目标是正确的。在一个星期内,这一目标是正确的
变量niz=sortirajPo.Split('.');
//在我的生活中,证明我的工作是正确的
if(niz.Length表达式.PropertyOrField(arg,niz[1]);
返回niz[2].ToLower()=“asc”?ovo.OrderBy(lambda).asc:ovo.OrderBy(lambda).Desc;
}
//你的名字叫vrcemo ovo bez ikakvog sortiranja
回卵;
}
}

这是
表达式.Lambda(body)
如果您知道如何生成
SomeObj=>SomeObj.SomeProp
,那么您应该能够通过调用
表达式.Lambda
仅指定body来生成没有参数的Lambda

因此,要想拥有
Foo=>body
,您需要执行以下操作:

var lambdaExpression = Expression.Lambda(bodyExpression, Expression.Parameter(typeof(int), "Foo"));
要拥有
()=>body
,您只需执行以下操作:

var lambdaExpression = Expression.Lambda(bodyExpression);
编辑:由于属性在运行时作为字符串提供(我猜它是属性名):


我终于成功了。问题在于NHibernate正在解析obj1.propert1.propert2,因为本地范围的lambda表达式。因此,我必须在运行时创建代码来创建新类并将其传递给方法

public static Type CreateMyNewType
 (string newTypeName, string propertyName, Type propertyType, Type baseClassType)
    {
        // create a dynamic assembly and module 
        AssemblyBuilder assemblyBldr =
        Thread.GetDomain().DefineDynamicAssembly(new AssemblyName("tmpAssembly"),
        AssemblyBuilderAccess.Run);
        ModuleBuilder moduleBldr = assemblyBldr.DefineDynamicModule("tmpModule");

        // create a new type builder
        TypeBuilder typeBldr = moduleBldr.DefineType
        (newTypeName, TypeAttributes.Public | TypeAttributes.Class, baseClassType);

        // Generate a private field for the property
        FieldBuilder fldBldr = typeBldr.DefineField
        ("_" + propertyName, propertyType, FieldAttributes.Private);
        // Generate a public property
        PropertyBuilder prptyBldr =
                    typeBldr.DefineProperty(propertyName,
            PropertyAttributes.None, propertyType, new Type[] { propertyType });
        // The property set and property get methods need the following attributes:
        MethodAttributes GetSetAttr = MethodAttributes.Public | MethodAttributes.HideBySig;
        // Define the "get" accessor method for newly created private field.
        MethodBuilder currGetPropMthdBldr =
                    typeBldr.DefineMethod("get_value", GetSetAttr, propertyType, null);

        // Intermediate Language stuff... as per Microsoft
        ILGenerator currGetIL = currGetPropMthdBldr.GetILGenerator();
        currGetIL.Emit(OpCodes.Ldarg_0);
        currGetIL.Emit(OpCodes.Ldfld, fldBldr);
        currGetIL.Emit(OpCodes.Ret);

        // Define the "set" accessor method for the newly created private field.
        MethodBuilder currSetPropMthdBldr = typeBldr.DefineMethod
        ("set_value", GetSetAttr, null, new Type[] { propertyType });

        // More Intermediate Language stuff...
        ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator();
        currSetIL.Emit(OpCodes.Ldarg_0);
        currSetIL.Emit(OpCodes.Ldarg_1);
        currSetIL.Emit(OpCodes.Stfld, fldBldr);
        currSetIL.Emit(OpCodes.Ret);
        // Assign the two methods created above to the PropertyBuilder's Set and Get
        prptyBldr.SetGetMethod(currGetPropMthdBldr);
        prptyBldr.SetSetMethod(currSetPropMthdBldr);
        // Generate (and deliver) my type
        return typeBldr.CreateType();
    }

   public static IQueryOver<TRoot, TSubType> UvediSortiranje<TRoot, TSubType, T>(this IQueryOver<TRoot, TSubType> ovo, string sortirajPo, T klasa, string naziv)
    {
        //provjeri da li sortiraj po zadovoljava konvenciju Objekat.Svojstvo i ako da, splituj ga na to
        var niz = sortirajPo.Split('.');
        // provjeri da li postoje ova svojstva u ovom objektu i da li se poklapaju imena

        if (niz.Length <= 0) return ovo;

        if (/*typeof(TSubType).Name == niz[0]*/ typeof(T).Name == niz[0])
        {
            //var arg = Expression.Constant(null, typeof(TSubType));
            //var body = Expression.Convert(Expression.PropertyOrField(arg, niz[1]),
            //    typeof(object));
            //var lambda = Expression.Lambda<Func<object>>(body);


            var tip = CreateMyNewType("brza2", naziv, typeof(T), typeof(object));

            var newClassBase = Activator.CreateInstance(tip);

            dynamic nesto = newClassBase;

            var parameter = Expression.Parameter(nesto.GetType());
            var memberExpression = Expression.Property(parameter, naziv);
            //var parameter2 = Expression.Parameter(typeof(T));
            var memberExpression2 = Expression.Property(memberExpression, niz[1]);
            Expression conversion = Expression.Convert(memberExpression2, typeof(object));
            var lambda = Expression.Lambda<Func<object>>(conversion);


            //lambda = (() => Expression.PropertyOrField(arg, niz[1]));

            return niz[2].ToLower() == "asc" ? ovo.OrderBy(lambda).Asc : ovo.OrderBy(lambda).Desc;
        }
        //u suprotnom vrcemo ovo bez ikakvog sortiranja
        return ovo;
    }
公共静态类型CreateMyNewType
(字符串newTypeName、字符串propertyName、类型propertyType、类型baseClassType)
{
//创建动态部件和模块
AssemblyBuilder assemblyBldr=
Thread.GetDomain().DefinedDynamicAssembly(新的AssemblyName(“tmpAssembly”),
AssemblyBuilderAccess.Run);
ModuleBuilder moduleBldr=assemblyBldr.DefinedDynamicModule(“tmpModule”);
//创建一个新的类型生成器
TypeBuilder typeBldr=moduleBldr.DefineType
(newTypeName,TypeAttributes.Public | TypeAttributes.Class,baseClassType);
//为属性生成专用字段
FieldBuilder fldBldr=类型BLDR.DefineField
(“_”+propertyName、propertyType、FieldAttributes.Private);
//生成公共属性
PropertyBuilder prptyBldr=
typeBldr.DefineProperty(propertyName,
PropertyAttributes.None,propertyType,新类型[]{propertyType});
//property set和property get方法需要以下属性:
MethodAttributes GetSetAttr=MethodAttributes.Public | MethodAttributes.HideBySig;
//为新创建的私有字段定义“get”访问器方法。
MethodBuilder currGetPropMthdBldr=
typeBldr.DefineMethod(“get_值”,GetSetAttr,propertyType,null);
//中级语言的东西…根据微软
ILGenerator currGetIL=currGetPropMthdBldr.GetILGenerator();
currGetIL.Emit(操作码.Ldarg_0);
currGetIL.Emit(操作码.Ldfld,fldBldr);
currGetIL.Emit(操作码Ret);
//为新创建的私有字段定义“set”访问器方法。
MethodBuilder currSetPropMthdBldr=类型BLDR.DefineMethod
(“set_value”,GetSetAttr,null,新类型[]{propertyType});
//更多中级语言的东西。。。
ILGenerator currSetIL=currSetPropMthdBldr.GetILGenerator();
currSetIL.Emit(操作码.Ldarg_0);
currSetIL.Emit(操作码Ldarg_1);
currSetIL.Emit(操作码Stfld、fldBldr);
currSetIL.Emit(操作码Ret);
//将上面创建的两个方法分配给PropertyBuilder的Set和Get
prptyBldr.SetGetMethod(currGetPropMthdBldr);
prptyBldr.SetMethod(currSetPropMthdBldr);
//生成(并交付)我的类型
返回typeBldr.CreateType();
}
公共静态IQueryOver UvediSortiranje(此IQueryOver ovo、string sortirajPo、T klasa、string naziv)
{
//证明扎多伏尔爪哇的目标是正确的。在一个星期内,这一目标是正确的
变量niz=sortirajPo.Split('.');
//在我的生活中,证明我的工作是正确的
if(niz.Length表达式.PropertyOrField(arg,niz[1]);
返回niz[2].ToLower()=“asc”?ovo.OrderBy(lambda).asc:ovo.OrderBy(lambda).Desc;
}
//你的名字叫vrcemo ovo bez ikakvog sortiranja
回卵;
}

对不起,对我的问题稍作更正。SomeProp应该在运行时作为字符串提供。因此,应该在方法中引入一些变量x=“SomeProp”。我会试试你的建议,但我肯定会更复杂?@user2779330基本上是一样的,真的。我对我的答案进行了编辑,但代码几乎没有任何变化。或者你的意思是“每次执行lambda”中的“运行时”,而不是“当构造lambda时”?@user2779330不是真的,我应该看到什么
public static Type CreateMyNewType
 (string newTypeName, string propertyName, Type propertyType, Type baseClassType)
    {
        // create a dynamic assembly and module 
        AssemblyBuilder assemblyBldr =
        Thread.GetDomain().DefineDynamicAssembly(new AssemblyName("tmpAssembly"),
        AssemblyBuilderAccess.Run);
        ModuleBuilder moduleBldr = assemblyBldr.DefineDynamicModule("tmpModule");

        // create a new type builder
        TypeBuilder typeBldr = moduleBldr.DefineType
        (newTypeName, TypeAttributes.Public | TypeAttributes.Class, baseClassType);

        // Generate a private field for the property
        FieldBuilder fldBldr = typeBldr.DefineField
        ("_" + propertyName, propertyType, FieldAttributes.Private);
        // Generate a public property
        PropertyBuilder prptyBldr =
                    typeBldr.DefineProperty(propertyName,
            PropertyAttributes.None, propertyType, new Type[] { propertyType });
        // The property set and property get methods need the following attributes:
        MethodAttributes GetSetAttr = MethodAttributes.Public | MethodAttributes.HideBySig;
        // Define the "get" accessor method for newly created private field.
        MethodBuilder currGetPropMthdBldr =
                    typeBldr.DefineMethod("get_value", GetSetAttr, propertyType, null);

        // Intermediate Language stuff... as per Microsoft
        ILGenerator currGetIL = currGetPropMthdBldr.GetILGenerator();
        currGetIL.Emit(OpCodes.Ldarg_0);
        currGetIL.Emit(OpCodes.Ldfld, fldBldr);
        currGetIL.Emit(OpCodes.Ret);

        // Define the "set" accessor method for the newly created private field.
        MethodBuilder currSetPropMthdBldr = typeBldr.DefineMethod
        ("set_value", GetSetAttr, null, new Type[] { propertyType });

        // More Intermediate Language stuff...
        ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator();
        currSetIL.Emit(OpCodes.Ldarg_0);
        currSetIL.Emit(OpCodes.Ldarg_1);
        currSetIL.Emit(OpCodes.Stfld, fldBldr);
        currSetIL.Emit(OpCodes.Ret);
        // Assign the two methods created above to the PropertyBuilder's Set and Get
        prptyBldr.SetGetMethod(currGetPropMthdBldr);
        prptyBldr.SetSetMethod(currSetPropMthdBldr);
        // Generate (and deliver) my type
        return typeBldr.CreateType();
    }

   public static IQueryOver<TRoot, TSubType> UvediSortiranje<TRoot, TSubType, T>(this IQueryOver<TRoot, TSubType> ovo, string sortirajPo, T klasa, string naziv)
    {
        //provjeri da li sortiraj po zadovoljava konvenciju Objekat.Svojstvo i ako da, splituj ga na to
        var niz = sortirajPo.Split('.');
        // provjeri da li postoje ova svojstva u ovom objektu i da li se poklapaju imena

        if (niz.Length <= 0) return ovo;

        if (/*typeof(TSubType).Name == niz[0]*/ typeof(T).Name == niz[0])
        {
            //var arg = Expression.Constant(null, typeof(TSubType));
            //var body = Expression.Convert(Expression.PropertyOrField(arg, niz[1]),
            //    typeof(object));
            //var lambda = Expression.Lambda<Func<object>>(body);


            var tip = CreateMyNewType("brza2", naziv, typeof(T), typeof(object));

            var newClassBase = Activator.CreateInstance(tip);

            dynamic nesto = newClassBase;

            var parameter = Expression.Parameter(nesto.GetType());
            var memberExpression = Expression.Property(parameter, naziv);
            //var parameter2 = Expression.Parameter(typeof(T));
            var memberExpression2 = Expression.Property(memberExpression, niz[1]);
            Expression conversion = Expression.Convert(memberExpression2, typeof(object));
            var lambda = Expression.Lambda<Func<object>>(conversion);


            //lambda = (() => Expression.PropertyOrField(arg, niz[1]));

            return niz[2].ToLower() == "asc" ? ovo.OrderBy(lambda).Asc : ovo.OrderBy(lambda).Desc;
        }
        //u suprotnom vrcemo ovo bez ikakvog sortiranja
        return ovo;
    }