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。真的吗?