8

データベース テーブルがItemあり、linq-to-sql でアクセスします。

Item.id の平方根が偶数の場合に true を返すアイテムのカスタム メソッド IsSpecial() を定義できます。

partial class Item
{
    public static Expression<Func<Item, bool>> IsSpecial = (i => Math.Sqrt(i.Id)%2==0);
}

次に、次のように linq-to-sql クエリでそのプロパティを使用できます。

 datacontext.Item.Where(Item.IsSpecial)

美的な理由から、 IsSpecial を非静的にして、次のように呼び出すことができるように変更したいと思います。

 datacontext.Item.Where(i => i.IsSpecial())

理想的には、これにより、上記の (動作中の) snytax では許可されていないステートメントの結合も許可されます。

 datacontext.Item.Where(i => i.IsSpecial() && i.Id >100)

このメソッドを定義するための正しい構文は何ですか?

これは動作しません:

partial class Item
{
    public Expression<Func<bool>> IsSpecial = ( () => Math.Sqrt(this.Id)%2==0 );
    // 'this' keyword not available in current context
}

編集: 構文が単に許可していないものを求めているのではないかと疑い始めています

私は一緒に暮らすことができると思いますdatacontext.Item.Where(Item.IsSpecial).Where(i => i>100)

4

3 に答える 3

4
partial class Item
{
    public static Expression<Func<Item, bool>> IsSpecial = (i => Math.Sqrt(i.Id)%2==0);
}

提案:readonlyキーワードを追加します。

次に、次のように linq-to-sql クエリでそのプロパティを使用できます。

datacontext.Item.Where(Item.IsSpecial)

そうです、 typeのWhereパラメーターを受け入れるためです。Expression<Func<Item, bool>>Item.IsSpecial

美的な理由から、 IsSpecial を非静的にして、次のように呼び出すことができるように変更したいと思います。

datacontext.Item.Where(i => i.IsSpecial())

これが機能しない理由IsSpecialは、 が関数ではなく、式ツリーであるためです。()関数にのみ適用できます。式ツリーは関数を記述しますが、関数ではありません。次を使用して実際の関数を作成できますexpression.Compile()

datacontext.Item.Where(i => (IsSpecial.Compile()) (i))

ただし、Where式ツリーが渡され、IsSpecial.Compile()実際には呼び出されないため、これは機能しません。LINQ to SQL はそれを SQL に変換しようとしますが、認識しないために失敗しExpression.Compile、例外がスローされます。

(IsSpecial.Compile())ただし、 LINQ to SQL が表示される前に置き換えることができれば...

それがLINQKitの出番です:

それを機能させるために、式ツリーの操作が少しだけ提供されます。

datacontext.Item.AsExpandable().Where(i => (IsSpecial.Compile()) (i))

は、式を事前にフィルタリングするため.AsExpandable()のラッパーを作成します。datacontext.Item

理想的には、これにより、上記の (動作中の) snytax では許可されていないステートメントの結合も許可されます。

datacontext.Item.Where(i => i.IsSpecial() && i.Id >100)

問題ない:

datacontext.Item.AsExpandable().Where(i => (IsSpecial.Compile()) (i) && i.Id > 100)
于 2012-04-12T18:26:36.143 に答える
1

IsSpecial への代入をコンストラクターに配置して、他のすべてのコンストラクターをそれに委譲するか、OnCreated などの部分メソッドを使用して式を IsSpecial に代入することもできます。の中にpartial class Item

partial void OnCreated()
{
     IsSpecial = () => Math.Sqrt(this.Id)%2==0;
}

これを行うと、常に IsSpecial が割り当てられ、「this」へのアクセスが許可されます。

于 2012-04-12T17:21:51.837 に答える