Можно ли использовать take в выражении запроса в c # linq вместо использования .Take (x)? - PullRequest
2 голосов
/ 31 октября 2008

Я пытаюсь написать код LINQ To SQL, который генерировал бы SQL, например

SELECT t.Name, g.Name
FROM Theme t
INNER JOIN (
    SELECT TOP 5 * FROM [Group] ORDER BY TotalMembers
) as g ON t.K = g.ThemeK

Пока у меня есть

var q = from t in dc.Themes 
join g in dc.Groups on t.K equals g.ThemeK into groups 
select new { 
    t.Name, Groups = (from z in groups orderby z.TotalMembers select z.Name )
};

но мне нужно сделать топ / взять подзапрос упорядоченных групп. Согласно http://blogs.msdn.com/vbteam/archive/2008/01/08/converting-sql-to-linq-part-7-union-top-subqueries-bill-horst.aspx в VB я мог просто добавить TAKE 5 в конце, но я не могу заставить этот синтаксис работать в c #. Как вы используете синтаксис take в c #?

edit: PS, добавляющий .Take (5) в конце заставляет его запускать загрузки отдельных запросов

edit 2: Я допустил небольшую ошибку с намерением SQL выше, но вопрос все еще остается. Проблема в том, что если вы используете в запросе методы расширения, такие как .Take (5), LinqToSql выполняет множество SQL-запросов вместо одного запроса.

Ответы [ 3 ]

4 голосов
/ 31 октября 2008

Второй ответ, теперь я перечитал оригинальный вопрос.

Вы уверены, что указанный вами SQL действительно верен? Он не даст 5 лучших групп в каждой теме - он сопоставит каждую тему только с 5 основными группами в целом .

Короче говоря, я подозреваю, что вы получите исходный SQL, если вы используете:

var q = from t in dc.Themes 
join g in dc.Groups.OrderBy(z => z.TotalMembers).Take(5)
  on t.K equals g.ThemeK into groups 
select new { t.Name, Groups = groups };

Но я не думаю, что это то, что вы на самом деле хотите ...

2 голосов
/ 31 октября 2008

Просто заключите в скобки свое выражение запроса и вызовите Take on:

var q = from t in dc.Themes 
join g in dc.Groups on t.K equals g.ThemeK into groups 
select new { t.Name, Groups = 
       (from z in groups orderby z.TotalMembers select z.Name).Take(5) };

На самом деле, выражение запроса на самом деле не упрощает вас - вы могли бы также напрямую вызвать OrderBy:

var q = from t in dc.Themes 
join g in dc.Groups on t.K equals g.ThemeK into groups 
select new { t.Name, Groups = groups.OrderBy(z => z.TotalMembers).Take(5) };
1 голос
/ 31 октября 2008

Вот точный перевод оригинального запроса. Это не должно генерировать повторные циклы.

var subquery =
  dc.Groups
  .OrderBy(g => g.TotalMembers)
  .Take(5);

var query =
  dc.Themes
  .Join(subquery, t => t.K, g => g.ThemeK, (t, g) => new
  {
    ThemeName = t.Name, GroupName = g.Name
  }
  );

Круглые обходы в вопросе вызваны присоединением группы (присоединиться к). Группы в LINQ имеют иерархическую форму. Группы в SQL имеют форму строки / столбца (сгруппированные ключи + агрегаты). Чтобы LinqToSql заполнил свою иерархию из результатов строки / столбца, он должен запросить дочерние узлы отдельно, используя ключи группы. Это происходит только в том случае, если дети используются вне совокупности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...