2

カスタム プロパティを 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;
        }
    }
}

そして、ラムダ式でこのプロパティを使用する必要があります。

activeUsers = users.Where(u => u.IsActive);

しかし、このコードが実行されると、System.NotSupportedException. 例外メッセージには、「メンバー 'User.IsActive' の SQL 変換はサポートされていません」と記載されています。

この問題を解決する方法はありますか?

4

3 に答える 3

6

あなたIsActiveが示しているのは通常のC#です-ILにコンパイルされ、LINQ-to-SQL(など)が検査してTSQLに変換してデータベースで実行することはできません。ここでの1つのオプションは次のとおりです。

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 を作成できます。

于 2013-02-06T10:25:21.280 に答える
2

次のことを試すことができます。

activeUsers = users.AsEnumerable().Where(u => u.IsActive);

ただし、IsActive の背後にあるロジックはデータベースの観点からは不明であるため、基準 IsActive は SQL に変換されないことに注意してください。したがって、データベースはテーブル ユーザー全体に対して読み取りを実行し、条件がメモリ内で適用されます。

于 2013-02-06T10:07:45.307 に答える
1

私はこの方法で同様の問題を解決しました:

私のORMはNHibernateで、基礎となるDBは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);
于 2013-02-06T10:56:15.697 に答える