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