[英]Custom properties and lambda expressions
我已經為LINQ-to-SQL實體添加了一個自定義屬性:
public partial class User
{
public bool IsActive
{
get
{
// note that startDate and endDate are columns of User table
return startDate <= DateTime.Now && endDate >= DateTime.Now;
}
}
}
現在我需要將此屬性與lambda表達式一起使用:
activeUsers = users.Where(u => u.IsActive);
但是當執行此代碼時,我得到一個System.NotSupportedException
。 異常消息說“不支持成員'User.IsActive'的SQL轉換” 。
有沒有辦法解決這個問題?
您展示的IsActive
是常規C# - 它將被編譯為IL,並且不可用於LINQ-to-SQL(等)以檢查並轉換為TSQL以在數據庫中執行。 這里的一個選擇可能是:
public static Expression<Func<User,bool>> GetIsActiveFilter() {
return user => user.StartDate <= DateTime.Now &&
user.EndDate >= DateTime.Now;
}
那么你應該可以使用:
activeUsers = users.Where(User.GetIsActiveFilter());
或者類似 - 可能是一種擴展方法:
public static IQueryable<User> ActiveOnly(this IQueryable<User> users) {
return users.Where(user => user.StartDate <= DateTime.Now &&
user.EndDate >= DateTime.Now);
}
然后:
activeUsers = users.ActiveOnly();
這里的區別在於我們始終使用IQueryable<T>
接口和表達式樹 ,這允許LINQ理解我們的意圖 ,並創建合適的TSQL來實現相同的目的。
您可以嘗試以下方法:
activeUsers = users.AsEnumerable().Where(u => u.IsActive);
請注意,標准IsActive將不會轉換為SQL,因為從數據庫角度來看,不了解IsActive背后的邏輯。 因此,數據庫將對整個表用戶執行讀取,並且標准將應用於內存中。
我用這種方式解決了類似的問題:
我的ORM是NHibernate,底層的數據庫是Oracle,當我需要添加像IsActive這樣的字段時,做了類似這樣的事情
public partial class User
{
public bool IsActive{get;set;}
}
在相關的映射文件中添加這樣的東西
<property name="IsActive" access="property" insert="false" update="false"
formula="case when startDate <= sysdate And endDate >= sysdate then 1 else 0 end" />
現在你可以使用了
activeUsers = users.Where(u => u.IsActive);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.