Отношение родитель-потомок в запросе Linq

В классе сущностей

У меня есть две родительские таблицы «TestParent» и «TestTag» в классе Entity и одна из дочерних таблиц. «TestChild», который не обновляется в классе Entity. поэтому я могу присоединиться к таблицам TestParent и TestChild (оба являются первичными отношениями foreinkey).

Проблема: я не могу выбрать дочернюю таблицу TestChild в запросе Linq

Таблица: TestTag:

Отношение родитель-потомок в запросе Linq

Таблица: TestParent:

Отношение родитель-потомок в запросе Linq

Детская таблица: TestChild

Отношение родитель-потомок в запросе Linq

В классе Entity ниже

public DbSet<TestParent> Questions { get; set; }
  public DbSet<TestTag> Tags { get; set; }

<Вопрос> связан с TestParent? Если нет, укажите TestParent Класс сущности? Также я не вижу никакой связи между TestParent и TestChild.

Bijay Koirala 15.02.2019 06:39

@BijayKoirala, извините, я обновил, пожалуйста, проверьте это

Sajith 15.02.2019 07:42

Еще одна вещь, ты забыл update TestChild, так как я не вижу, как TestTag, TestParent and TestChild связаны?

Bijay Koirala 15.02.2019 07:48

Пожалуйста, предположим, что в таблице TestChild -> TagId является первичным ключом таблицы TestParent. Я имею в виду, что таблица TestParent и TestChild дала отношение первичного ключа внешнего ключа. Таблица TestTag не имеет никакого отношения.

Sajith 15.02.2019 07:56

Тогда вы не сможете присоединиться к Linq. Если вы не планируете изменять класс сущностей, чтобы добавить TestChild, вы можете создать store procedure, где вы можете выполнить соединение и получить данные из кода, вызывающего sp.

Bijay Koirala 15.02.2019 08:02

Если я изменю отношение, например, в таблице TestChild, TagId является первичным ключом таблицы TestTag, а QuestionId является первичным ключом таблицы TestParent. Тогда возможно ли присоединиться к таблице TestChild в запросе Linq без добавления таблицы TestChild в класс Entity. Есть ли запрос на выборку в linq. Мне нужно выбрать записи из таблицы TestParent на основе TagId, значение которого я передаю в таблицу TestChild.

Sajith 15.02.2019 10:10

Давайте продолжить обсуждение в чате.

Sajith 15.02.2019 10:22
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
1 498
1

Ответы 1

Итак, у вас есть три таблицы: таблица TestTags, таблица TestParents и таблица с TestChildren.

Каждый TestTag имеет ноль или более TestChildren; каждый TestChild принадлежит ровно одному TestTag с использованием внешнего ключа. Прямое отношение «один ко многим»

Каждый TestParent также имеет ноль или более TestChildren; каждый TestChild имеет ровно один TestParent, используя внешний ключ.

Если бы вы следовали Первые соглашения кода фреймворка сущностей, у вас было бы что-то похожее на

class TestTag
{
    public int Id {get; set;}
    ...  // other properties

    // every TestTag has zero or more TestChildren (one-to-many)
    public virtual ICollection<TestChild> TestChildren {get; set;}
}
class TestParent
{
    public int Id {get; set;}
    ...  // other properties

    // every TestParent has zero or more TestChildren (one-to-many)
    public virtual ICollection<TestChild> TestChildren {get; set;}
}
class TestChild
{
    public int Id {get; set;}
    ...  // other properties

    // every TestChild has exactly one TestParent using foreign key
    public int TestParentId {get; set;}
    public virtual TestParent TestParent {get; set;}

    // every TestChild has exactly one TestTag using foreign key
    public int TestTagId {get; set;}
    public virtual TestTag TestTag {get; set;}
}

In entity framework the columns of the tables are represented by non-virtual properties. The virtual properties represent the relations between the tables (one-to-many, many-to-many, ...)

Таким образом, TestTag 4 и TestParent 5 могут иметь двух дочерних элементов. Если вы не хотите, рассмотрите возможность создания комбинированного первичного ключа [TestTagId, TestParentId].

Если TestChild не имеет других свойств, кроме внешних ключей, то на самом деле вы создаете отношение «многие ко многим» между TestTag и TestParent. В этом случае вам не нужно упоминать таблицу TestChild.

Для полноты DbContext:

class MyDbContext : DbContext
{
     public DbSet<TestTag> TestTags {get; set;}
     public DbSet<TestParent> TestParents {get; set;}
     public DbSet<TestChild> TestChildren {get; set;}
}

Это все, что необходимо знать инфраструктуре сущностей для обнаружения ваших отношений, а также первичных и внешних ключей. Поскольку я следовал условным атрибутам, свободный API не нужен, за исключением, может быть, из-за нестандартной формы множественного числа Children.

so can I Join the TestParent and TestChild table

Ну, вы можете присоединиться к (группе), но обычно проще использовать ICollections

Дайте мне TestParents, которые... со всеми их TestChildren и TestTags, которые...

var result = dbContext.TestParents
    .Where(parent => ...)             // if you don't want all testParents
    .Select(parent => new
    {
        // select only the properties you plan to use
        Id = parent.Id,
        Name = parent.Name,

        Children = parent.TestChildren
            .Where(child => child.TestTag.Name = "My Test Tag Name")
            .Select(child => new
            {
                Name = child.TestTag.Name,
                ...
            })
            .ToList(),
    });

Некоторые люди вместо этого предпочитают использовать GroupJoin. Если вы этого хотите и можете убедить руководителя проекта в том, что GroupJoin удобнее для чтения/тестирования/сопровождения, чем использование ICollections, вы можете сделать следующее:

var result = dbContext.TestParents.GroupJoin(dbContext.TestChildren,
    parent => parent.Id,                // from each parent take the Id
    child => child.ParentId,            // from each child take the ParentId

    // resultSelector:
    (parent, children) => new
    {
        // Parent Properties:
        Id = parent.Id,
        ...

        // GroupJoin the collection of child properties with the TestTags:
        children.GroupJoin(dbContext.TestTags,
        child => child.TestTagId,          // from each TestChild take the TestTagId
        tag => tag.Id,                     // from each TestTag take the Id
        (child, tagsOfThisChild) => new
        {
            // desired Child properties
            ...

            TestTags = tagsOfThisChild.Select(tag => new
            {
                 Id = tag.Id,
                 ...
            })
            .ToList(),
        })
        .ToList(),
    });

ИМХО: выглядит ужасно!

Мне нужно только вернуть записи таблицы «TestParents» на основе TagId таблицы «TestChild». Я буду передавать "tagId"

Sajith 22.02.2019 16:13

Другие вопросы по теме