2011-07-27 19 views
1

私は、プロジェクトを標準のDBクエリを使って作業することから、EFとLINQの作業に移しています。私は、そのクエリを構築するために、テーブルから、クライアントや都市を引っ張っされるだろう、私の元のテーブルでは匿名クラス/プロパティを持つLINQ

select * from client where city = ? 

:私は、私は次のようになり、クエリを構築するために使用する特定のレコードを持つテーブルを持っています。

上記のクライアントと都市が、別の表やフィールドになる可能性もあります。 EFとLINQで同じことをどうすればできますか?これも可能ですか、そのロジックをすべて処理するために別のクラスを構築する必要がありますか?

var query = from c in context.clients 
      where c.city == ? 
      select c; 

編集:これはクエリに参加することではありません。それは動的クエリを構築することです。私は都市、住所、または "クライアント"テーブル自体でさえも問いませんか、プログラムをいつ実行するのか分かりません。それは別のテーブルにある可能性があります。私は動的にクエリを構築できるようにしたい。

+2

もっと詳しい情報が必要だと思います。表の定義を見てみましょう。 –

+3

明確にしてください。私はあなたが欲しいものに続く問題を抱えています –

答えて

0

動的なクエリをEntity Frameworkで構築する場合は、式ツリーを動的に構築する手間を省くことができます。ただし、Entity Frameworkにはいくつかの追加オプションがあります。

まず、EntityObjectは、すでにあなたが文字列を構築し、含む述語の数に直接それをで通過させるいくつかの追加オブジェクトサービスのメソッドがあります。

c.Customers.Where("City = 'London'"); 

あなたは大きなクエリを構築する必要がある場合は、クエリソースを動的に設定するなど、EntitySQLの使用を検討してください。 EntitySQLとたとえば、あなたは単純な文字列の解析を使用して、次のようなコードを生成することができます。

string entitySQL = "SELECT VALUE c FROM Customers AS c WHERE c.Address.City = 'Seattle';"; 
ObjectQuery<Customer> query = context.CreateQuery<Customer>(entitySQL); 

あなたはEntity Framework Query Samplesでのアクションでこれらのオプションの両方を見ることができます。

+0

これは私がここで探している行に沿っています。ありがとうございます。これにより、設計時に「顧客」が何であるかわからない場合、実行時にどのようにキャストするのですか? (「顧客」、「注文」など) – Zteck

+0

実行時に結果ソースまたは投影列を動的に設定する場合は、context.CreateQuery を使用する必要があります。ここでは、EFサンプルの例を示します。string entitySQL = "SELECT Min(p.UnitPrice)AS MinPrice、p.Category.CategoryName製品からAS p GROUP BY p.Category。CategoryName; "; ObjectQuery query = context.CreateQuery (entitySQL); –

0

テーブルが外部キーによって結合されている場合、次のようにLINQを使用して別のテーブルの値にアクセスできます。 (私はそこに「アドレス」テーブルだと、クライアントテーブルがそれへの外部キーを持っていると仮定して、あなたの例を拡張しています。)

var query = from c in context.clients 
      where c.address.city == ? 
      select c; 

編集:(あなたの元の質問とフォローのコメントを理解しようとしています。 ..)

I だと思います。あなたはこのようなことができるかどうかということですか?

string cityName = "Los Angeles"; // Could be a parameter, etc. 

var query = from c in context.clients 
      where c.city == cityName 
      select c; 

それとも、多分このような何か、あなたの質問からさらに一歩それを取るために:それはのIQueryableですので

string cityName = (from c in context.cities 
        where c.id == 5 
        select c.name).FirstOrDefault(); 

var query = from c in context.clients 
      where c.city == cityName 
      select c; 

、あなたはその場で、だけでなく、さらに条件を追加することができます。

if (someCondition) 
{ 
    query = from q in query 
      where q.someField >= conditionValue 
      select q; 
} 

などです。クエリ式ツリーは、実際に結果が必要になるまで実際には評価/実行されません。

+0

私ははっきりしてはいけません。私は元のクエリを持っていましたが、クライアントと都市はテーブルによって提供された文字列値で、私はその場でクエリを構築していました。私は、LINQを使ってEFで同じことをやりたいと思っていて、そのLINQクエリをその場で構築したいと思っています。これは可能ですか? – Zteck

+0

ええ、あなたは明確ではありませんでした。だから、あなたの質問であったことを元のクエリから再確認するには、実行時に '?'を提供できるかどうかを知りたいでしょうか? – GalacticCowboy

+0

それはあなたが求めているものではない場合、多分詳細を提供するためにあなたの質問を編集することができますか? – GalacticCowboy

0

あなたは両方のクエリは、内部生成されます

var query = from c in context.clients 
     join add in context.Addresses on c.AddressID equals add.AddressID 
     where addr.city == ? 
     select c; 

ようGalacticCowboyによって提示されたクエリを書くことができますが、性能に差がない参加します。唯一の違いは、アドレスがクライアントの場合はオプションです。c.address.Cityはアドレスを持たないクライアントで例外をスローしますが、このクエリは空の列挙を返します。

0

実際に実行時にクエリを作成する場合は、使用可能なlinqベースのソリューションのうち、実行時にコードをコンパイルして一時アセンブリにすることができます。また、MSの例の1つでDynamicLinqを使用することもできます。詳細情報については

、中に質問と回答を参照してください。私はあなたが取ることができるいくつかの方法があると思いHow to create LINQ Query from string?

0

まず、Dynamic LINQ libraryを調べることができます(また、David Fowlerのアップデートhereも参照してください)。このアプローチを使用すると、このようなあなたのLINQクエリを書くことができます。

var results = Context.Clients 
       .Where("city=='Los Angeles'") 
       .OrderBy("address"); 

は、だからあなたの WhereOrderBy述語がフードの下式に変換します文字列です。

第二に、あなたはあなたが1つまたは複数のフィールドを照会することがあります場合は必ずあなたがオンに問い合わせるか知っているが、開始されない場合のように、PredicateBuilderのようなライブラリを使用することができます

var predicate = PredicateBuilder.True<Clients>(); 
foreach(var criteria in searchCriteria) { 
    if (criteria.Key=="city"){ 
    predicate = predicate.And(c => c.city==criteria.Value); 
    } else if (criteria.Key=="address"){ 
    predicate = predicate.And(c => c.address==criteria.Value); 
    } 
} 
var results = Context.Clients.Where(predicate); 

第三に、そしておそらく最も難しいのは、独自のExpression Treeを構築することです。これは間違いなく最も多くのコードを必要とします(最初は少し深いですが)、非常に強力です。 MSDNからのexampleは、できることについて十分に説明しています(そして、私がここで行うことができるよりもはるかに簡潔になります)。

基本的に、利用できるオプションはいくつかあります。ダイナミックLINQライブラリは使いやすいと思われますが、私はそれを使ったことがないので、どれくらいうまく動作し、どれくらい信頼できるのかは分かりません。ダイナミックLINQライブラリ用のNuGetパッケージもあります。

幸運。お役に立てれば!

+0

これはすべてLINQ to SQLに適用されますが、EFにはすでに述語ビルダーを必要とせずに文字列を渡すことができるObject Servicesメソッドがあります。実際には式ツリーに変換されるのではなく、標準的なクエリ式に変換されます。 –

関連する問題