2009-08-03 23 views
0

私はサーバー名とログインを持つテーブルを持っています。私は、サーバーのグループ全体で共通のログインを取得する必要があります。私はサーバ1、サーバ2に渡しとUser2は、関連のServer1ないようバックのみのUser1になるだろうLINQ to SQL - クエリで悩む

ServerName Login 
------------------------------- 
Server1  User1 
Server2  User1 
Server2  User2 

は、次のデータが与えられました。

LINQ to SQLでこれがどのように達成されるのか誰にでも教えてください。

私はContainsを試しましたが、私が探しているものとは逆の種類のサーバーのすべてのユーザーを返します。

EDIT:私の同僚の一人は、私が後だ何のSQLのバージョンを記述するために管理....

SELECT Login 
    FROM ServerLogins 
    WHERE ServerName IN ('Server1', 'Server2') 
GROUP BY Login 
HAVING count(Login) = 2 

が、私たちのどちらもLINQクエリにこれを翻訳する方法を知っています。

追加EDIT:

ライアンの助けを借りて、私は仕事に以下しまっVBとC#の間LINQの違いのいくつかのグーグルで。

Dim logins = From l In dc.ServerLogins _ 
      Where servers.Contains(l.ServerName) _ 
      Group l By l.Login Into Group _ 
      Where Group.Count() = servers.Count _ 
      Select Login 

おかげさまで、皆様のおかげで、

ニック

+1

あなたが試しているLINQ文を教えてもらえますか? –

+1

コード例を投稿できますか? – sloth

答えて

2

これは私が思いついたものです。おそらくあなたがそれを心配している場合、実際に生成されたSQLを確認して調べることをお勧めします。

List<string> servers = new List<string>{"Server1", "Server2"}; 

var logins = from l in context.ServerLogins 
      where servers.Contains(l.ServerName) 
      group l by l.Login into g 
      where g.Count() == servers.Count 
      select g.Key; 
+0

私たちはこれに近づいていましたが、私はコンパイルエラー "メソッドの定義gはこの文脈ではアクセスできない "。 私がVBで作業しているためかどうかはわかりません。 – Nick

+0

これはC#ではうまくいくはずだと思いますが、私はVBのLinqに慣れていません。私は周りを見回そうとしているので、あなたのためにそれを修正することができます。 –

+0

'g'の代わりに' Group'を使う必要があるようです。私は本当に確信していない...私はいくつかのネットワークの問題があるので、私は多くのまともなリソースにアクセスすることはできません。 –

0

個人的に私は、これはLINQ to SQLのを使用するために、代わりのSPROCまたは標準のSQLクエリのいずれかを使用しない良い場所だと思います。私はあなたがLinqで正しいクエリを思いついても、それは非常に読みやすく、効率的ではないと思います。

あなたが持っているでしょうSQLは次のようになります。最後の行に「2」( "IN(」上記のリストでサーバ名の数で交換する必要があることを

SELECT Login 
FROM ServerLogins 
WHERE ServerName IN ('Server1', 'Server2') 
GROUP BY Login 
HAVING COUNT(*) = 2 

は注意をServer1 '、' Server2 ') ")。

+0

Spooky、これはちょうど私たちが出てきた正確な文です。 これは現在sprocで行われていますが、連続する数字と一時テーブルのテーブルを使用して、カンマで区切られたサーバ名のリストをINステートメントが実行され、私はこれを行う必要がない(または実行時に文字列にSQLを書く必要がある)のが好きです – Nick

0

限り、私はこのようなものでいいと思うに渡されているサーバの#上の合理的な実用上の限界がありますよう:

public ICollection<Login> GetLoginsForServers(params string[] servers) 
{ 
    if (servers == null || servers.Length == 0) 
     return new List<Login>(); 

    var logins = db.Logins.Where(p => p.ServerName == servers[0]); 
    for (int i=1; i<servers.Length; i++) 
    { 
     logins = logins.Intersect(db.Logins.Where(p => p.ServerName == servers[i])); 
    } 

    return logins.ToList(); 
} 

は、基本的には、関連付けられたすべてのログインを開始しているが、第1のサーバは、その後の各サーバに関連するサーバによってそれを制限する。クエリはToList()まで実行されないため、データベースは一度だけクエリされますが、クエリ自体は醜いものですが、LINQ2SQLプロバイダは効率的なクエリプランを生成するものを生成することが望ましいでしょう。