У меня проблемы с запросом, написанным на LINQ и Lambda. Пока что я получаю много ошибок, вот мой код:
int id = 1;
var query = database.Posts.Join(database.Post_Metas,
post => database.Posts.Where(x => x.ID == id),
meta => database.Post_Metas.Where(x => x.Post_ID == id),
(post, meta) => new { Post = post, Meta = meta });
Я новичок в использовании LINQ, поэтому я не уверен, что этот запрос правильный.
Ответы:
Я обнаружил, что если вы знакомы с синтаксисом SQL, использование синтаксиса запросов LINQ намного яснее, естественнее и облегчает обнаружение ошибок:
Если вы действительно застряли на использовании лямбда-выражений, ваш синтаксис немного нарушен. Вот тот же запрос, использующий методы расширения LINQ:
источник
lambda
и цитата проста в использовании и пониманииВы можете пойти двумя путями с этим. Используя LINQPad (неоценимо, если вы новичок в LINQ) и фиктивную базу данных, я построил следующие запросы:
или
В этом конкретном случае, я думаю, что синтаксис LINQ чище (я переключаюсь между двумя в зависимости от того, какой из них легче всего читать).
Однако я хотел бы отметить, что если в вашей базе данных есть соответствующие внешние ключи (между post и post_meta), то вам, вероятно, не понадобится явное соединение, если вы не пытаетесь загрузить большое количество записей. , Ваш пример показывает, что вы пытаетесь загрузить один пост и его метаданные. Предполагая, что для каждого поста существует много записей post_meta, вы можете сделать следующее:
Если вы хотите избежать проблемы n + 1, то вы можете явно указать LINQ to SQL, чтобы загружать все связанные элементы за один раз (хотя это может быть сложной темой, когда вы более знакомы с L2S). В приведенном ниже примере говорится, что «когда вы загружаете сообщение, также загружайте все его записи, связанные с ним, через внешний ключ, представленный свойством Post_metas»:
Можно сделать много
LoadWith
вызовов на одном набореDataLoadOptions
для одного и того же типа или для множества разных типов. Если вы делаете это много, вы, возможно, просто захотите рассмотреть кеширование.источник
У Даниэля есть хорошее объяснение синтаксических взаимосвязей, но я собрал этот документ для своей команды, чтобы сделать его немного более простым для понимания. Надеюсь, это поможет кому-то
источник
Post_ID
поле во втором псевдонимеmeta => meta.Post_ID
. В примере на этом рисункеg.id
часть исходного оператора selectJOIN gStatus g on g.id
не реплицируется в конечном лямбда-выражении.public class IdHolder{ int id }
то использовал бы этот объект в gStatus,List<IdHolder> gStatus = new List<IdHolder>(); gStatus.add(new IdHolder(){id = 7}); gStatus.add(new IdHolder(){id = 8});
тогда он изменил бы Linq, чтобы бытьt =>t.value.TaskStatusId, g=>g.id
, это изменение имеет смысл?Ваши ключевые селекторы неверны. Они должны взять объект типа рассматриваемой таблицы и вернуть ключ для использования в соединении. Я думаю, что вы имеете в виду это:
Вы можете применить предложение where позже, а не как часть ключевого селектора.
источник
Публикация, потому что, когда я начал LINQ + EntityFramework, я смотрел на эти примеры в течение дня.
Если вы используете EntityFramework, и у вас есть свойство навигации, названное
Meta
в вашемPost
объекте модели, это очень просто. Если вы используете сущность и у вас нет этого свойства навигации, чего вы ждете?Если вы сначала делаете код, вы должны настроить свойство следующим образом:
источник
Я сделал что-то вроде этого;
источник
Это может быть что-то вроде
источник
1 равняется 1 разному соединению таблицы
источник
Этот запрос linq должен работать для вас. Он получит все сообщения, которые имеют мета-пост.
Эквивалентный SQL-запрос
источник