Question

What I want basically is to be able to to the following (following is psuedo code)

string SelectField = cb1.Name.Substring(2);
MyContext.Items.Select(x=>x.SelectField )

I tried the following:

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)

but it gave me the error:

The LINQ expression node type 'Lambda' is not supported in LINQ to Entities.

Is this possible? I just want to be able to select a single entity property based on the selection of my combobox.

Était-ce utile?

La solution

I was able to get my desired results using the following code (not much different then my original attempt)

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);

All I was missing was the Func line. It now works as I wanted.

Autres conseils

Ok, so with this type of solution you're likely going to have to do a bunch of reflection to get it to work dynamically.

string SelectField = cb1.Name.Substring(2);
ParameterExpression pe = Expression.Parameter(typeof(Item), "p");

First you have to invoke the lambda method without knowing the complete return type. The return type is Expression<Func<Item, ?>> (with the question mark being a placeholder for the property type.

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 } });

Then we have to invoke the select method in a similar fashion because the property type isn't know until runtime.

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 });

I don't know what you're doing with the query variable so I can't provide any further guidance with that at this time. Again, in this example we don't know what type will be contained in the collection until runtime because it is a collection of the property values.

FYI: My method for selecting the correct lambda and select was a total hack. You really should create a more robust search method examing the signature more completely to ensure you've found the correct method you are needing. I can provide a better example later if you need it when I have more time.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top