创建一个 Dynamic Linq to EF Expression to Select IQueryable into new class 并分配属性
Create a Dynamic Linq to EF Expression to Select IQueryable into new class and assign properties
我正在尝试动态创建与以下 Linq 等效的内容。
IQueryable<TypeOne> ones;
ones.Select(i => new TypeTwo { TwoProp = i.OneProp });
到目前为止我有以下代码,但它不是。
public class TypeOne
{
public string OneProp { get; set; }
}
public class TypeTwo
{
public string TwoProp { get; set; }
}
public static IQueryable<TypeTwo> Tester(IQueryable<TypeOne> data)
{
ConstructorInfo constructor = typeof(TypeTwo ).GetConstructor(new Type[] { });
Expression body = Expression.New(constructor);
ParameterExpression oneParam = Expression.Parameter(typeof(TypeOne), "one");
Expression prop1 = Expression.Property(oneParam, "OneProp");
ParameterExpression twoParam = Expression.Parameter(typeof(TypeTwo ), "two");
Expression prop2 = Expression.Property(twoParam, "TwoProp");
Expression assign = Expression.Assign(prop2, prop1);
body = Expression.Block(body, assign);
return data.Select(Expression.Lambda<Func<TypeOne, TypeTwo >>(body, oneParam));
}
但是我得到以下异常:
附加信息:类型 'System.String' 的表达式不能用于 return 类型 'TypeTwo'
你应该使用 Expression.MemberInit,像这样:
public static IQueryable<TypeTwo> Tester(IQueryable<TypeOne> data)
{
var source = Expression.Parameter(typeof(TypeOne), "source");
var selector = Expression.Lambda<Func<TypeOne, TypeTwo>>(
Expression.MemberInit(Expression.New(typeof(TypeTwo)),
Expression.Bind(typeof(TypeTwo).GetProperty("TwoProp"), Expression.Property(source, "OneProp"))),
source);
return data.Select(selector);
}
您可以包含任意数量的 Expression.Bind
表达式(即 属性 赋值)。
我正在尝试动态创建与以下 Linq 等效的内容。
IQueryable<TypeOne> ones;
ones.Select(i => new TypeTwo { TwoProp = i.OneProp });
到目前为止我有以下代码,但它不是。
public class TypeOne
{
public string OneProp { get; set; }
}
public class TypeTwo
{
public string TwoProp { get; set; }
}
public static IQueryable<TypeTwo> Tester(IQueryable<TypeOne> data)
{
ConstructorInfo constructor = typeof(TypeTwo ).GetConstructor(new Type[] { });
Expression body = Expression.New(constructor);
ParameterExpression oneParam = Expression.Parameter(typeof(TypeOne), "one");
Expression prop1 = Expression.Property(oneParam, "OneProp");
ParameterExpression twoParam = Expression.Parameter(typeof(TypeTwo ), "two");
Expression prop2 = Expression.Property(twoParam, "TwoProp");
Expression assign = Expression.Assign(prop2, prop1);
body = Expression.Block(body, assign);
return data.Select(Expression.Lambda<Func<TypeOne, TypeTwo >>(body, oneParam));
}
但是我得到以下异常:
附加信息:类型 'System.String' 的表达式不能用于 return 类型 'TypeTwo'
你应该使用 Expression.MemberInit,像这样:
public static IQueryable<TypeTwo> Tester(IQueryable<TypeOne> data)
{
var source = Expression.Parameter(typeof(TypeOne), "source");
var selector = Expression.Lambda<Func<TypeOne, TypeTwo>>(
Expression.MemberInit(Expression.New(typeof(TypeTwo)),
Expression.Bind(typeof(TypeTwo).GetProperty("TwoProp"), Expression.Property(source, "OneProp"))),
source);
return data.Select(selector);
}
您可以包含任意数量的 Expression.Bind
表达式(即 属性 赋值)。