【问题标题】:LINQ to Entities does not recognize the method 'System.Object GetValue(...)'LINQ to Entities 无法识别方法“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 返回该属性为真。

标签: c# linq entity-framework-6


【解决方案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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-22
        • 1970-01-01
        • 1970-01-01
        • 2019-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多