Как разделить два списка одного класса на разные таблицы в Entity Framework?

В моем проекте у меня есть следующие классы:

public class Dot
{
    public int Id { get; set; }
    public int Value { get; set; }
    // some more information
}

public class TimeRow
{
    public int Id { get; set; }
    public List<Dot> Fact { get; set; }
    public List<Dot> Forecast { get; set; }
}

И я хочу, чтобы Fact и Forecast находились в разных таблицах базы данных. Есть ли хороший способ сделать это?

Мои мысли

Возможно, я могу сделать два класса FactDot и ForecastDot, которые наследуют класс Dot, сделать свойства List<FactDot> Fact и List<ForecastDot> Forecast, и эти списки будут в разных таблицах, но я не думаю, что это хорошее решение.

но я не думаю, что это хорошее решение. Почему это не хорошее решение? Один класс не может быть сопоставлен с двумя таблицами. Но тогда зачем две разные таблицы?

Gert Arnold 22.12.2020 16:26

@GertArnold Печально, что нет возможности иметь разные таблицы (( В будущем я хочу добавить больше списков в класс TimeRow, например: OptimisticForecast, PessimisticForecast и даже еще один класс TimeRow_2. Если они будут храниться в одной таблице, эта таблица будет много столбцов Id's, что не очень хорошо для понимания структуры БД.

LK1nn 22.12.2020 16:43

Я думаю, что TimeRow должен иметь только Dots и Dot какое-то поле типа. В бизнес-логике вы можете сделать различие, как в доменном классе TimeRow, который просто возвращает различные коллекции с помощью простого Where. Это позволяет вам добавлять столько типов точек, сколько вы хотите, даже не меняя модель данных.

Gert Arnold 22.12.2020 16:56

@GertArnold Хм ... Это, вероятно, решит мою проблему, я попробую. Спасибо)

LK1nn 22.12.2020 17:31
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
57
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Иметь класс Forecast без полей, наследуемый от Dot.

public class Dot
{
    public int Id { get; set; }
    public int Value { get; set; }
    // some more information
}

public sealed class Forecast : Dot
{
}

public class TimeRow
{
    public int Id { get; set; }
    public List<Dot> Fact { get; set; }
    public List<Forecast> Forecast { get; set; }
}

В будущем я хочу добавить больше списков в TimeRow class, например: OptimisticForecast, PessimisticForecast. Это означает, что мне придется добавить еще два простых класса, таких как Forecast. Но в бизнес-логике я хочу работать с Dots, значит ли это, что мне понадобится еще один класс между БД и бизнес-логикой для приведения к нему TimeRow?

LK1nn 22.12.2020 17:47
Ответ принят как подходящий

и эти списки будут в разных таблицах, но я не думаю, что это хорошее решение.

На самом деле, это хорошее решение. :)

public class Dot
{
    public int Id { get; set; }
    public int Value { get; set; }
    // some more information
}

public class Fact : Dot
{ }

public class Forecast : Dot
{ }

public class TimeRow
{
    public int Id { get; set; }
    public virtual ICollection<Fact> Facts { get; set; } = new List<Fact>();
    public virtual ICollection<Forecast> Forecasts { get; set; } = new List<Forecast>();
}

Почему? Потому что только сегодня это не кажется необходимым. Факт и прогноз выглядят одинаково, поэтому наличие двух классов с одинаковыми полями кажется «неправильным». Но это не одно и то же, даже если в настоящее время они выглядят одинаково. Их нужно хранить отдельно, и кто сказал, что в будущем не будет полей, которые были бы действительно полезны только для одной из этих сущностей? Вы не захотите добавлять Null-able условные поля в Dot, более разумно поместить в Fact поле, специфичное для факта. Это держит этот путь полностью открытым.

Если вы добавите другие классы, расширяющие Dot, что с того? они представляют собой буквально две строки кода и могут полагаться на соглашение EF для сопоставления. :) Наследование Dot — это просто контракт, по которому их можно рассматривать «как» Dot. У них по-прежнему есть своя особая цель, даже если данные, которые они хранят, пока не отличаются.

Спасибо за ответ, наверное продолжу работу в этом направлении разными классами)

LK1nn 23.12.2020 09:21

Всегда лучше иметь только одну таблицу вместо двух, если это возможно. Это позволяет повторно использовать большой объем кода и значительно упрощает выполнение различных запросов. Итак, я рекомендую:

public class Dot
{
    public int Id { get; set; }
    public int Value { get; set; }

    public int TimeRowId { get; set; } 
    public int DotType {get; set;} in this case you can use 0-Fact, 1-Forecast
    // or maybe this: public string DotType {get; set;} in this case you can use just "Fact" or "Forecast"

....  // some more information
}

public class TimeRow
{
    public int Id { get; set; }
    public virtual List<Dot> Dots { get; set; }
  
}

или, может быть, в вашем случае вы обнаружите, что лучше перенести DotType из класса Dot в класс TimeRow:


public class TimeRow
{
    public int Id { get; set; }
 public int DotType {get; set;} in this case you can use 0-Fact, 1-Forecast
    // or maybe this: public string DotType {get; set;} in this case you can use just "Fact" or "Forecast"

    public virtual List<Dot> Dots { get; set; }
  
}

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