簡體   English   中英

自定義屬性和lambda表達式

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM