Индивидуальное упорядочение Linq to Entities через таблицу сопоставления позиций - PullRequest
3 голосов
/ 25 апреля 2010

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

Затем я ВЛЕВО НАРУЖНО присоединяюсь к таблице позиций ON news.newsId = position.itemId с оператором выбора регистра

CASE WHEN [position] IS NULL THEN 9999 ELSE [position] END

и порядок по позиции asc, articleDate desc.

Теперь я пытаюсь сделать то же самое с Linq to Entities. Я установил в своих таблицах отношения PK, FK, чтобы у моего объекта News была коллекция позиций Entity.

Теперь наступает момент, когда я не могу работать. Как реализовать LEFT OUTER JOIN.

У меня так далеко:

 var query = SelectMany (n => n.Positions, (n, s) => new { n, s })
                    .OrderBy(x => x.s.position)
                    .ThenByDescending(x => x.n.articleDate)
                    .Select(x => x.n);

Это вроде работает. Однако здесь используется ВНУТРЕННЕЕ СОЕДИНЕНИЕ, а не то, что мне нужно.

У меня была другая идея:

 ret = ret.OrderBy(n => n.Positions.Select(s => s.position));

Однако я получаю сообщение об ошибке У выражений DbSortClause должен быть тип, сопоставимый по порядку.

Я тоже пробовал

ret = ret.GroupJoin(tse.Positions, n => n.id, s => s.itemId, (n, s) => new { n, s })
                    .OrderBy(x => x.s.Select(z => z.position))
                    .ThenByDescending(x => x.n.articleDate)
                    .Select(x => x.n);

но я получаю ту же ошибку!

Если кто-нибудь может мне помочь, это будет высоко ценится!

UPDATE:
Поэтому после некоторой игры мне удалось заставить ее работать.

ret = ret.GroupJoin(entity.Positions, n => n.id, s => s.itemId, (n, s) => new { n, s })
                    .SelectMany(x => x.n.Positions.DefaultIfEmpty(), (n, s) => new { n, s })
                    .OrderBy(x => x.s.position)
                    .ThenByDescending(x => x.n.n.articleDate)
                    .Select(x => x.n.n);

Однако это все еще не совсем верно. У меня нет возможности использовать только определенный positionid или articleType.

Если у меня есть идентификатор новостей 1 и идентификатор обзора, но они определены в таблице позиций, в настоящее время (я думаю) запрос linq будет выбирать оба?

Если я попытаюсь использовать предложение where, это в основном то же самое, что и внутреннее соединение. Что мне нужно, так это попробовать использовать регистр в select, как если бы я использовал обычный SQL:

CASE WHEN [position] IS NULL OR shuffleId != 1 THEN 9999 ELSE [position] END

Возможно, мне придется полностью переосмыслить, как это сделать. Не думаете ли вы, что у кого-нибудь есть альтернативные методы?

Ответы [ 2 ]

2 голосов
/ 30 апреля 2010

Как насчет:

var query =
   from n in news
   let p = n.Positions.Select(p=>p.Position).FirstOrDefault() ?? 9999
   orderby p, n.ArticleDate
   select n;

Ps. Вышеприведенное предполагает, что для каждой новости есть только 1 позиция ... просто кажется странным, если бы это было не так.


Решение, опубликованное OP в комментарии ниже:

ret = ret
      .GroupJoin(tse.Positions, n => n.id, s => s.itemId, (n, s) => new { n, s }) 
      .SelectMany(x => x.s.DefaultIfEmpty(), (n, s) => new { n, s }) 
      .OrderBy(x => x.s.position == null || x.s.positionId != positionId ? 9999 : x.s.position) 
      .ThenByDescending(x => x.n.n.articleDate) 
      .Select(x => x.n.n);
1 голос
/ 04 мая 2010

Все, что я могу вам предложить, это использовать какой-нибудь метод хранимой процедуры - добавьте его в ваше решение с помощью нового класса Linq-To-SQL, а затем используйте DataContext, чтобы получить результат. В этом случае вы не будете использовать запрос к базе данных, и это хорошо для вашего решения.

Единственная проблема в том, что тип результата этой процедуры может быть несовместим с вашим классом новостей Возможно, вам придется написать некоторый код для преобразования одного представления в другое.

При необходимости я могу предоставить некоторые иллюстрации для моего обходного пути.

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