Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
675 views
in Technique[技术] by (71.8m points)

c# - LINQ to Entities does not recognize the method 'System.Object GetValue(...)'

My issue is I need to query on the value of a property in a generic class. The property is tagged with an attribute.

See the following code:

 var rowKeyProperty = EFUtil.GetClassPropertyForRowKey<T>();
 var tenantKeyProperty = EFUtil.GetClassPropertyForTenantKey<T>();

 var queryResult =
                objContext.CreateObjectSet<T>().Single(l => (((int) tenantKeyProperty.GetValue(l, null)) == tenantKey) &&
                                                            (((int)rowKeyProperty.GetValue(l, null)) == KeyValue));

The rowKeyProperty and tenantKeyProperty are of type System.Reflection.PropertyInfo.

I understand why I am getting the error. When the linq query is translated to SQL, it can't understand the property.GetValue.

However, I'm completely stumped as to a work around here. Does anyone have any ideas how to achieve this? Thx.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You need to actually build up the Expression objects to represent the expression that you want this to mimic, in this case the expression you want to represent is:

l => l.SomeProperty == SomeValue

So you need to build up each component of that bit by bit, from creating the parameter, defining the equality operator, the property access, the constant value, etc.

public static Expression<Func<TItem, bool>> PropertyEquals<TItem, TValue>(
    PropertyInfo property, TValue value)
{
    var param = Expression.Parameter(typeof(TItem));
    var body = Expression.Equal(Expression.Property(param, property),
        Expression.Constant(value));
    return Expression.Lambda<Func<TItem, bool>>(body, param);
}

Once you have all of that you can call it using the data that you have:

var queryResult = objContext.CreateObjectSet<T>()
    .Where(PropertyEquals<T, int>(tenantKeyProperty, tenantKey))
    .Where(PropertyEquals<T, int>(rowKeyProperty, KeyValue))
    .Single();

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...