2009-09-01 7 views
2

を表現します私はそれを共有することができるものにリファクタリングしたかったのです。私はそれをSQLに変換することができないとして、私は通常の方法でこれを行うことはできません知っているが、私もどちらか動作するようにオプションは、私は、具体的句は、同じコンプレックスを含むSQLクエリへのLINQのペアを持って

Expression < Func<...>>

ものdescribed hereを取得することはできません。私はここに私の正気の目的のためにwhere句を簡素化した場合

は、私は式に

where (range.MinumumFrequency < minFreq) 

をオンにしたいので、私は試してみました:

public static Expression<Func<FreqRange, bool>> Overlaps(decimal minMHz, decimal maxMHz) 
{ 
    return (range => range.MinimumFrequency <= minMHz); 
} 

これはコンパイルに表示されますが、私はどこのステートメントが動作するように見えることはできません、私は次を試した:

where FreqRange.Overlaps(minMHz, maxMHz) 

しかし、これは私を与えるコンパイル時エラー:

Cannot implicitly convert type 'System.Linq.Expressions.Expression>' to 'bool'

アイデアはありますか?また、私たちがこれを働かせたとすれば、式< Func < >>のラムダ式を拡張して他の条件を含めることはできますか?

答えて

2

あなたは、言語builting LINQの構文を使用する場合は、暗黙的にラムダ式を宣言している - あなたは、あなたがリターンに式をwhere句を必要としない -ラムダ式がExpression<Func <>>であることとになる必要がありますの表現。

だけでなくrow.a < aMax、あなたがするかどうか -

var q = from row in myTable 
     where row.a < aMax 
     select row.b; 

// which translates to 

var q = myTable.Where(row => row.a < aMax).Select(row => row.b); 

は今、あなたは "キャッシュ" row => row.a < aMaxする必要があります。あなたはこのような何かを書くことだったのであれば、...

Expression<Func<?,bool>> cachedExpression = row => row.a < aMax; 

var q = from row in myTable 
     where cachedExpression 
     select row.b; 

はさて、あなたはどこ、行与えられ、(行与えられ、row.aがあることは事実であることは事実である」と言っていますaMaxより小さい)」。これはナンセンスであり、cachedExpressionのタイプがExpression<Func<?,bool>>で、myTableがLinqToSqlの提供されたテーブルである場合はコンパイルされません。

Expression<Func<?,bool>> cachedExpression = row => row.a < aMax; 

//nonsense .Where: 
var q = myTable.Where(row => cachedExpression).Select(row => row.b); 
//effectively says this: 
var q = myTable.Where(row => (row0 => row0.a < aMax)).Select(row => row.b); 

は今、これは、非ブール値を持つwhereclauseを実装するためにLINQクエリプロバイダの可能であるという意味で、法的ですが、それはだ:それはこのような何かに変換でしょう非常に奇妙なことをする;確かに標準のlinqプロバイダ(LinqからSqlへ)はそういったことをしません。

なのでとなりますか?次のようなものがあります。

//not .Where(row=>cachedExpression)! 
var q = myTable.Where(cachedExpression).Select(row => row.b); 

//or, alternatively: 
var q = from filteredRow in myTable.Where(cachedExpression) 
     select filteredRow.b; 
1

また、IQueryableを受け取り、送信するメソッドを作成することもできます。私はこれらのビューを純粋にコードで使用しました。

public class WithProps 
{ 
    public string Prop1 { get; set; } 
    public string Prop2 { get; set; } 
    public override string ToString() 
    { 
     return string.Format("{0}-{1}", Prop1, Prop2); 
    } 
} 

public static class Tools 
{ 
    public static IQueryable<WithProps> MyFilter(this IQueryable<WithProps> props) 
    { 
     return props.Where(p => p.Prop1 == "hi"); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var propList = new List<WithProps>() 
     { 
      new WithProps(){ Prop1="hi", Prop2="there"}, 
      new WithProps(){ Prop1="hi", Prop2="bye"}, 
      new WithProps(){ Prop1="hello", Prop2="world"}, 
      new WithProps(){ Prop1="bye", Prop2="friend"} 
     }; 

     var filtered = propList.AsQueryable().MyFilter(); 

     Console.WriteLine("propList ==="); 
     foreach (var item in propList) 
      Console.WriteLine(item.ToString()); 
     Console.WriteLine("filtered ==="); 
     foreach (var item in filtered) 
      Console.WriteLine(item.ToString()); 
    } 
} 

...結果...

propList === 
hi-there 
hi-bye 
hello-world 
bye-friend 
filtered === 
hi-there 
hi-bye 
関連する問題