C # / EF Core: Работа с (историческими) датами / периодами - PullRequest
1 голос
/ 03 июля 2019

Для веб-сайта C # с использованием ASP.NET Core Mvc с использованием SQL Server и EF Core.

Для хобби-проекта я ищу старые газеты, документы и ищу конкретные здания. Каждый раз, когда я нахожу информацию о таком здании, я пытаюсь записать информацию о дате. Так что я могу отслеживать, в какое время это здание было там.

Допустим, я наткнулся на Build X и увидел дату 1880 года. Я записал дату 1880. Несколько недель спустя я снова встречаю здание X и вижу дату: 16.03.1877. Теперь я знаю, что здание было там наверняка с 16.03.1877 по 1880 год.

Период: 16/03/1877 - 1880

  • Теперь в некоторых зданиях нет информации о дате.
  • В некоторых зданиях есть только одна дата (возможно, при дополнительном исследовании можно найти другое)
  • Некоторые здания могут иметь информацию о том, что они существовали в 17 веке (без указания конкретного года или даты).
  • даты могут содержать год, год + месяц или год + месяц + день

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

Будет ли достаточно 2 свойств модели?

public class Building {
[DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
  public DateTime? Date1 { get; set; }
[DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? Date2 { get; set; }
}

Подойдет ли это для поисковых фильтров на сайте. Например. поиск всего между 1830 - 1930 или все 17 века.

В последнем вопросе я имею в виду, как бы вы написали запрос linq, если бы для здания была указана только одна дата (например, 1835). Будет ли в каждом запросе дополнительная проверка на обнуляемую дату, если указана только одна дата? или есть лучшие сценарии?

.Where(x => x.Date1 != null && x.Date1 >= 1830 && (x.Date2 == null || x.Date2 <= 1930))

Или сохраняет DateTime? объект не очень хорошая идея и лучше хранить короткое или целое число и отслеживать только компонент года (если есть)?

1 Ответ

1 голос
/ 03 июля 2019

Действительно, ваша проблема сводится к отображению точных и «нечетких» дат. Единой стратегии не существует, но у меня было несколько похожее требование, и я выполнил его, указав дату начала, нечеткое начало, дату окончания и нечеткое окончание, все обнуляемые.

Если вам вообще известна какая-либо точная часть даты, вы используете поле фактической даты и времени. Например, если вы знаете только 1880, вы сохраняете его как 1880-01-01. Если вы знаете год и месяц, вы просто делаете день 01, и, конечно, если вы знаете полную дату, вы сохраняете ее. Теперь, конечно, это может быть проблематично. Откуда вы знаете, что он был построен не 1 января 1880 года, а в 1880 году? Что ж, решать вам, как справиться с такими ситуациями, решать вам. Вы можете просто предположить, что любое значение 01 совпадает со значением NULL для этой части даты. По какой-то причине здания не имеют тенденцию открываться 1 января или фактически 1-го числа любого месяца, но всегда может быть исключение.

Если вам нужна более высокая точность, вам может потребоваться разбить дату и сохранить ее буквально как год, месяц и день - все столбцы int со значением NULL. Затем вы можете просто собрать его вместе, как захотите, когда придет время его отобразить.

«Нечеткие» столбцы дат будут строками, и в них будет храниться больше «дат» туманностей, таких как «Викторианская эра», т.е. у вас может не быть точной даты или даже года, но вы знаете, что это было в какой-то период времени. Вы могли бы сделать то же самое с такими вещами, как «19-й век», но я лично предпочел бы сохранить это как 1800-01-01, а затем интуитивно понять, что он должен отображаться как «19-й век», когда есть дата этой формы.

Другой вариант - использовать как дату, так и нечеткий текст. Например, вы можете сохранить его как 1800-01-01 и"19-й век", а затем вы можете определить, что это не буквально 1 января 1800 года, на основании наличия нечеткого текста, не быть нулевым Это может помочь решить проблему неоднозначности, описанную ранее, как вы могли бы сделать это для всех таких случаев. Например, если все, что вы знаете, это «июль 1880 года», то вы можете сохранить это в нечетком тексте и установить дату как 1880-07-01. Затем, исходя из наличия нечеткого текста, вы можете выбрать расшифровку части 01 как практически нулевой по сравнению с буквально первым месяцем. Если нет нечеткого набора текста, то вы предполагаете, что это точная дата.

Что касается представления его в вашей модели, я бы не использовал фактические свойства DateTime или DisplayFormat. Вам бы лучше иметь служебные методы, которые могут работать над логикой и возвращать предварительно отформатированную «дату». Затем вы просто сделаете что-то вроде @building.GetBuiltDisplay() и вернете всю информацию, которую вы знаете (включая начало и конец, если она у вас есть), уже отформатированную.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...