我的问题是我需要查询泛型类中属性的值。该属性标有属性。
请参阅以下代码:
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。
但是,我对这里的工作感到非常难过。有没有人有任何想法如何实现这一目标? THX。
答案 0 :(得分:19)
您需要实际构建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();
答案 1 :(得分:3)
此处的附录...在@Servy回答并基于this主题和@TomBrothers的一个很好的答案之后,您可以使用相同的逻辑来创建StartsWith
(或类似)函数:< / p>
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
为字符串。
答案 2 :(得分:1)
在 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; }
}
答案 3 :(得分:0)
您在LINQ语句后添加.AsEnableable。 例如objectdata.AsEnumerable() enter link description here