2009-08-03 2 views
0

У меня есть таблица с именами серверов и входами. Мне нужно получить логины, которые являются общими для всей группы серверов.LINQ to SQL - Борьба с запросом

Учитывая следующие данные:

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

Я бы пройти в Server1, Server2 и получить обратно только User1, как Пользователь2 не связан Сервер1.

Может ли кто-нибудь сказать мне, как это будет достигнуто в LINQ to SQL?

Я попытался Содержит, но это возвращает меня всех пользователей на любом из серверов, который является видом противоположности тому, что я ищу.

EDIT: Один из моих коллег удалось написать версию SQL, что я после ....

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

, но ни один из нас знает, как перевести это в запросе LINQ.

ДОПОЛНИТЕЛЬНЫЕ EDIT:

С помощью Райана и некоторые Googling различий в LINQ между VB и C# Я получил следующие работы.

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#, но я не так хорошо знаком с Linq в VB. Я пытаюсь оглянуться, чтобы, возможно, исправить это для вас. –

+0

Похоже, вам может понадобиться использовать 'Group' вместо' g'. Я действительно не уверен, хотя ... У меня возникают проблемы с сетью, поэтому я не могу получить доступ к многим достойным ресурсам. –

0

Лично я думаю, что это хорошее место, чтобы НЕ использовать Linq для SQL и вместо того, чтобы использовать либо sproc или стандартный SQL запрос. Я думаю, что даже если вам нужно будет найти правильный запрос в Linq, он не будет очень читабельным и/или эффективным.

SQL, вы должны были бы выглядеть примерно так:

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

Обратите внимание, что «2» в последней строке следует заменить с числом имен серверов в списке выше ("IN (» 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(); 
} 

В основном вы начинаете со всеми логинами, связанных с первый сервер затем ограничивает его теми, которые связаны с каждым последующим. Поскольку запрос не выполняется до тех пор, пока ToList() все равно не будет запрашивать базу данных один раз, и хотя сам запрос будет уродливым, существует надежда, что поставщик LINQ2SQL генерирует что-то, что приведет к эффективному тарифному плану.

 Смежные вопросы

  • Нет связанных вопросов^_^