LINQ to Entities 无法识别方法“System.Object GetValue(...)”

Posted

技术标签:

【中文标题】LINQ to Entities 无法识别方法“System.Object GetValue(...)”【英文标题】:LINQ to Entities does not recognize the method 'System.Object GetValue(...)' 【发布时间】:2014-02-28 19:21:38 【问题描述】:

我的问题是我需要查询泛型类中属性的值。该属性带有一个属性标记。

见以下代码:

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

rowKeyProperty 和tenantKeyProperty 的类型是System.Reflection.PropertyInfo。

我明白为什么我会收到错误消息。 linq查询翻译成SQL时,无法理解property.GetValue。

但是,我对这里的工作完全感到困惑。有谁知道如何实现这一目标?谢谢。

【问题讨论】:

使用反射属性构建与 EF 兼容的查询的唯一方法是自己构建表达式树。 您如何确定需要获取哪些属性? 有一个与属性关联的属性。我调用attribute.isdefined 返回该属性为真。 【参考方案1】:

您需要实际构建Expression 对象来表示您希望它模仿的表达式,在这种情况下,您要表示的表达式是:

l => l.SomeProperty == SomeValue

所以你需要从创建参数、定义相等运算符、属性访问、常量值等一点一点地构建该组件的每个组件。

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

一旦你拥有了所有这些,你就可以使用你拥有的数据来调用它:

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

【讨论】:

确认这会在 SQL 分析器中生成正确的查询。谢谢服务。 当 param 为 DateTime 时,这有问题。 @muttley91 你遇到了什么问题? 日期时间时Expression.Property(param, property) 出错。 Property 'System.DateTime LastUpdate' is not defined for type 'DataAccess.WorkOrder' @YusrilMaulidanRaji 你的错误是告诉你出了什么问题。对于您尝试从中获取它的对象,没有该名称和类型的属性。【参考方案2】:

此处是附录...根据@Servy 的回答并基于@TomBrothers 的一个很好回答的this 主题,您可以使用相同的逻辑来制作StartsWith(或类似的)函数:

public static Expression<Func<TItem, bool>> PropertyStartsWith<TItem>(PropertyInfo propertyInfo, string value)

    var param = Expression.Parameter(typeof(TItem));

    var m = Expression.MakeMemberAccess(param, propertyInfo);
    var c = Expression.Constant(value, typeof(string));
    var mi = typeof(string).GetMethod("StartsWith", new Type[]  typeof(string) );
    var body = Expression.Call(m, mi, c);

    return Expression.Lambda<Func<TItem, bool>>(body, param);

在这种情况下,它强制value 成为一个字符串。

【讨论】:

【参考方案3】:

Expression.Constant(value, typeof(TValue)))中指定类型更正确

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

或者,像这样,检查属性。 ChangeType

public static Expression<Func<TItem, bool>> PropertyEquals<TItem, TValue>(
        string property, TValue value)
    
        var xParameter = Expression.Parameter(typeof(TItem));
        var type = typeof(TItem).GetProperty(property).PropertyType;
        value = ChangeType<TValue>(value);
        BinaryExpression body = Expression.Equal(Expression.Property(xParameter, property), Expression.Constant(value, type));

        return Expression.Lambda<Func<TItem, bool>>(body, xParameter);
    

它是干什么用的。我检查所有对类的类引用,寻找“..ID”条目。某处我有一个类型“int”和“int?”。

public class BudgetLimit : BaseRecord

    [Required]
    public int DepartmentID  get; set;  
    public virtual Department Department  get; set;

    public int? ProjectID  get; set; 
    public virtual Project Project  get; set; 
 

【讨论】:

【参考方案4】:

您在 LINQ 语句之后添加 .AsEnableable。 例如 objectdata.AsEnumerable() enter link description here

【讨论】:

以上是关于LINQ to Entities 无法识别方法“System.Object GetValue(...)”的主要内容,如果未能解决你的问题,请参考以下文章

LINQ to Entities 无法识别方法 IsNullOrWhiteSpace

错误:LINQ to Entities 无法识别方法 DataLength

LINQ To Entities 无法识别方法 Last。真的吗?

LINQ To Entities 无法识别方法 Last。真的吗?

C# LINQ to Entities 无法识别方法“布尔”

我如何修复“LINQ to Entities无法识别方法”错误