У меня есть таблица новостей, и я хотел бы осуществить заказной заказ. Я делал это раньше с помощью таблицы позиционного отображения, в которой есть 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
Возможно, мне придется полностью переосмыслить, как это сделать. Не думаете ли вы, что у кого-нибудь есть альтернативные методы?