Метод Linq — Возвращает строки, найденные только в другой таблице

#c# #asp.net-core #.net-core #entity-framework-core #linq-method-syntax

Вопрос:

Я хочу вернуть теги из таблицы тегов, которые можно найти только в таблице TagRecipe. Как я могу это сделать?

             var dataTags = await _context.Tags
                .Include(tc => tc.TagCategory)
                .ToListAsync();
 
     public class Tag
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public ICollection<TagRecipe> TagRecipes { get; set; }

        public int TagCategoryID { get; set; }
        public TagCategory TagCategory { get; set; }
    }
 
     public class TagRecipe
    {
        public int TagId { get; set; }
        public int RecipeId { get; set; }
        public Tag Tag { get; set; }
        public Recipe Recipe { get; set; }
    }
 

Спасибо

Комментарии:

1. Не могли бы вы, пожалуйста, опубликовать как тег модели таблицы s, так и TagRecipe?

2. Никаких проблем, готово.

Ответ №1:

Попробуйте это

  var dataTags = await _context.TagRecipe
                .Include(tc => tc.Tag.TagCategory)
                .Select(i=> i.Tag)
                .ToListAsync();
 

или вы можете использовать этот синтаксис, если он вам больше нравится

 var dataTags = await _context.TagRecipe
                .Include(t => t.Tag)
                .ThenInclude(tc => tc.TagCategory)
                .Select(i=> i.Tag)
                .ToListAsync();
 

Комментарии:

1. Серж: Я полагаю, что ты пропускаешь .Distinct А. Представьте себе случай, когда объединенная таблица TagRecipe содержит 5 записей с тегом = 1.

Ответ №2:

Альтернатива, начинающаяся с использования тегов таблицы Join , вернет результат без дубликатов.

 var dataTags = db.Tags
    .Join(db.TagRecipes, tag => tag.Id, tagRecipe => tagRecipe.TagId, (tag, tagRecipe) => tag)
    .Include(tag => tag.TagCategory)
    .ToLookup(tag => tag.Id) // client-side from here
    .Select(grouping => grouping.First()) // to make distinct
    .ToList();
 

Будет сгенерирован прямой SQL

 SELECT "t"."Id", "t"."Name", "t"."TagCategoryId", "t1"."Id", "t1"."Name"
FROM "Tags" AS "t"
INNER JOIN "TagRecipes" AS "t0" ON "t"."Id" = "t0"."TagId"
INNER JOIN "TagCategories" AS "t1" ON "t"."TagCategoryId" = "t1"."Id"
 

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

Коды тегов таблиц, по-видимому, представляют собой объединенную таблицу во множестве между тегами таблиц и рецептами таблиц. Последнее не включено в вопрос, но я добавил его во время своих тестов.

Обратите внимание, что в ядре EF 5 отношения «многие ко многим» могут быть созданы без класса сущности для присоединяемой таблицы.