.net Lambda到表达式
如何生成这个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
() => 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;
}