Entity Framework Code First Left Join - PullRequest
3 голосов
/ 20 апреля 2011

DB Tables

Сначала я создал простую БД в коде EF, но, похоже, возникла проблема.

Что я хотел бы сделать, так это запросить DBContext для получения пользовательского объекта CheckedTag, в котором были бы все доступные теги и логическое поле флажка.

Code First абстрагирует таблицу «многие ко многим», и я не могу найти правильный запрос.

Я пытался

            var qry = from t in Db.Tags
                  from a in Db.Articles
                  where(a.Id == articleId) 
                  select new CheckedTag 
                         { 
                             Id = t.Id, 
                             Name = t.Name, 
                             PermanentUrl = t.PermanentUrl, 
                             Checked = t.Id == null ? false : true 
                         };

и рыскал в сети уже несколько часов.

Если бы articleId был равен 0, он извлек бы все теги и установил флажок в false, если articleId был для существующей статьи, все теги были бы возвращены, а проверенные теги были бы установлены в true .

Может ли кто-нибудь предложить запрос, который мне нужно использовать, чтобы получить этот результат?

Ответы [ 2 ]

4 голосов
/ 20 апреля 2011

если я правильно понимаю, вы хотели бы получить для конкретной статьи (с идентификатором 'articleId') список всех тегов (не только тех, которые у него есть) и поставить значение "Проверено" на значение true, если оно действительно, ложь в противном случае. Если это так, вот запрос, который я бы предложил:

var checkedTags= from t in Db.Tags
                 select new CheckedTag
                        {
                            Id = t.id,
                            Name = t.name,
                            PermanentUrl = t.PermanentUrl,
                            Checked = t.Articles.Any(a => a.Id == articleId)
                        };

Надеюсь, это поможет:)

Редактировать : заменено «Содержит» на «Любой». Спасибо @ Якимыч.

2 голосов
/ 21 ноября 2011

Я бы предложил одно небольшое улучшение в ответе AbdouMoumen.(проверено в .Net 4 с EF 4)

Я проверил с помощью SQL-профилировщика и оператора Checked = t.Articles.Any (...), пока он дает правильные результаты, он дает немного неэффективный код SQL.

(ПРИМЕЧАНИЕ: мой код имеет разные имена сущностей, но точно такой же сценарий)

создает этот код:

    CASE WHEN ( EXISTS (SELECT 
    1 AS [C1]
    FROM [dbo].[LocationFeatures] AS [Extent2]
    WHERE ([Extent1].[FeatureID] = [Extent2].[FeatureID]) AND (1 = [Extent2].[LocationID])
)) THEN cast(1 as bit) WHEN ( NOT EXISTS (SELECT 
    1 AS [C1]
    FROM [dbo].[LocationFeatures] AS [Extent3]
    WHERE ([Extent1].[FeatureID] = [Extent3].[FeatureID]) AND (1 = [Extent3].[LocationID])
)) THEN cast(0 as bit) END AS [C1]

Я протестировал, изменив его на 'Checked =(т. статьи. Любые (...))?true: false 'результирующие данные совпадают с немного лучшим кодом SQL.это выдает:

CASE WHEN ( EXISTS (SELECT 
    1 AS [C1]
    FROM [dbo].[LocationFeatures] AS [Extent2]
    WHERE ([Extent1].[FeatureID] = [Extent2].[FeatureID]) AND (1 = [Extent2].[LocationID])
)) THEN cast(1 as bit) ELSE cast(0 as bit) END AS [C1]

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

...