[英]Use reflection and lambda expression with linq
我需要verifing標志命名的值篩選項目的集合deletion_date
public List<T> GetAll()
{
if (context == null) context = new ajtdevEntities();
return context.Set<T>().Where(p => p.GetType().GetProperty("deletion_date") == null).ToList();
}
使用此通用方法時出現異常
LINQ to Entities無法識別方法'System.Reflection.PropertyInfo GetProperty(System.String)',后者無法轉換為術語存儲。
如何解決此方法?
您可以使用System.Linq.Expressions
這樣手動構建篩選器表達式,而不是反射:
public List<T> GetAll<T>()
{
var parameter = Expression.Parameter(typeof(T), "p");
var predicate = Expression.Lambda<Func<T, bool>>(
Expression.Equal(Expression.PropertyOrField(parameter, "deletion_date"), Expression.Constant(null)),
parameter);
if (context == null) context = new ajtdevEntities();
return context.Set<T>().Where(predicate).ToList();
}
請注意,如果您的類型沒有名為“ deletion_date”的屬性/字段,或者該屬性的類型不支持null
,則上述內容將引發異常。 但是對於基於反射的實現(如果可行)也可以這樣說。
ORM將檢查lambda並將其部分轉換為SQL。 實體框架團隊選擇不支持反思,這是正確的。 因此它無法將GetProperty()
調用轉換為SQL,因此會出現錯誤。
無論如何,它將無法正常工作,因為GetProperty()
獲取的是PropertyInfo
實例,而不是值。 因此,如果為null
,則表明p
的類型沒有名為deletion_date
屬性。
正確的方法是在PropertyInfo
上調用GetValue()
(請注意,如果沒有這樣命名的PropertyInfo
,這將引發NullReferenceException
):
p => p.GetType().GetProperty("deletion_date").GetValue(p)
但是同樣,實體框架不支持反射,因此您要使用接口:
public interface IDeletable
{
DateTime? deletion_date { get; set; }
}
並將其作為一般約束應用於您的類或方法。 然后,您可以在lambda中使用它:
public class WhateverClass<T>
where T : IDeletable
{
public List<T> GetAll()
{
return context.Set<T>().Where(p => p.deletion_date == null).ToList();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.