我想要的基本上是能够进行以下操作(以下是伪代码)
string SelectField = cb1.Name.Substring(2);
MyContext.Items.Select(x=>x.SelectField )
我尝试了以下内容:
string SelectField = cb1.Name.Substring(2);
ParameterExpression pe = Expression.Parameter(typeof(Item), "p");
var expr = Expression.Lambda(Expression.Property(pe, SelectField), pe);
query = MyContext.Items.Select(p=>expr)
但它给了我错误:
The LINQ expression node type 'Lambda' is not supported in LINQ to Entities.
这可能吗?我只想根据组合框的选择选择单个实体属性。
答案 0 :(得分:1)
我能够使用以下代码获得我想要的结果(与我原来的尝试没有太大区别)
string SelectField = cb1.Name.Substring(2);
ParameterExpression pe = Expression.Parameter(typeof(Item), "p");
Expression expr = Expression.Lambda(Expression.Property(pe, SelectField), pe);
Expression<Func<Item, string>> expression = (Expression<Func<Item, string>>)expr;
var query = MyContext.Items.Select(expression);
我失踪的是Func系列。它现在可以正常使用。
答案 1 :(得分:0)
好的,所以使用这种类型的解决方案,您可能需要进行一系列反射才能使其动态运行。
string SelectField = cb1.Name.Substring(2);
ParameterExpression pe = Expression.Parameter(typeof(Item), "p");
首先,您必须在不知道完整返回类型的情况下调用lambda方法。返回类型为Expression<Func<Item, ?>>
(问号是属性类型的占位符。
var propertyType = typeof(Item).GetProperty(SelectField).GetGetMethod().ReturnType;
var lambdaMethodParamType = typeof(Func<,>).MakeGenericType(typeof(Item), propertyType);
var lambdaMethod = typeof(Expression).GetMethods().First(x => x.Name == "Lambda" && x.IsGenericMethod).MakeGenericMethod(lambdaMethodParamType);
var expr = lambdaMethod.Invoke(null, new object[] { Expression.Property(pe, SelectField), new ParameterExpression[] { pe } });
然后我们必须以类似的方式调用select方法,因为直到运行时才知道属性类型。
var selectMethod = typeof(Queryable).GetMethods().First(x => x.Name == "Select").MakeGenericMethod(typeof(Item), propertyType);
var query = (IQueryable)selectMethod.Invoke(null, new object[] { MyContext.Items, expr });
我不知道你在使用查询变量做什么,所以我目前无法提供任何进一步的指导。同样,在此示例中,我们不知道在运行时将包含哪个类型,因为它是属性值的集合。
仅供参考: 我选择正确的lambda和select的方法是完全黑客攻击。你真的应该创建一个更强大的搜索方法来更完整地检查签名,以确保你找到了你需要的正确方法。如果你有更多时间,我可以在以后提供更好的例子。