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

#c# #entity-framework

#c# #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 , который наследует class Dot , создавать свойства List<FactDot> Fact , List<ForecastDot> Forecast и эти списки будут находиться в разных таблицах, но я не думаю, что это хорошее решение.

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

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

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

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

4. @Гертарнольд Хм… Это, вероятно, решит мою проблему, я попробую это. Спасибо)

Ответ №1:

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

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

 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>();
}
 

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

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

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

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

Ответ №2:

Есть класс прогноза без полей, который наследуется от 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; }
}
 

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

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

Ответ №3:

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

 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; }
  
}