给定一个使用ASP.NET Core Mvc和SQL Server和EF Core的C#网站。
对于一个爱好项目,我正在寻找旧报纸,文件并寻找特定的建筑物。每次我找到此类建筑物的信息时,我都会尝试写下日期信息。这样我就可以跟踪这座建筑物在哪个时期。
假设我碰到Build X并看到了日期1880。我写下了date 1880
。几周后,我再次遇到了X楼,看到日期:16/03/1877。我现在知道建筑物可以肯定地从16/03/1877到1880。
期间:16/03/1877-1880
Now what would be the best to store this in the database and represent this in a model.
Would 2 properties on a model be sufficient?
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; }
}
Would it be suitable for search filters on the website. E.g. searching everything between 1830 - 1930 or everything from 17th century.
With the last question, I mean, how would you write a linq query if there is only one date given for a building (e.g. 1835). Would each query contain an extra check for the nullable date in case there is only a single date given? or are there better scenarios?
.Where(x => x.Date1 != null && x.Date1 >= 1830 && (x.Date2 == null || x.Date2 <= 1930))
Or is saving a DateTime? object not a good idea and better to store a short or integer and only keep track of the year component (if any)?
Really, your problem boils down to showing exact vs "fuzzy" dates. There's no one single strategy, but I've had a somewhat similar requirement before and handled it by having a start date, a fuzzy start, an end date, and a fuzzy end, all nullable.
如果您完全知道日期的确切部分,请使用实际的datetime字段。例如,如果您只知道1880,则将其存储为1880-01-01
。如果您知道年和月,则只需输入天01
,当然,如果您知道完整的日期,则可以存储该日期。现在,理所当然,这可能会带来问题。您怎么知道它不是从1880年1月1日开始建造的,而是从一般意义上来说是1880年建造的?好吧,这取决于您决定如何处理这些情况。您可以假定任何01
与该日期部分的空值相同。无论出于何种原因,建筑物都不会在1月1日或实际上在每个月的1号开放,但是那里总是有例外。
如果确实需要更高的精度,则可能需要分开日期并将其逐字存储为年,月和日-所有可为int的int列。然后,您可以简单地将其拼凑在一起,但是可以随时进行显示。
“模糊的”日期列将是字符串,并且您将在其中存储更多的星云“日期”,例如“维多利亚时代”,即您可能没有真实的日期甚至年份,但您知道它是在一段时间内。您可以对“ 19世纪”之类的东西进行同样的操作,但是我个人更喜欢将其存储为1800-01-01,然后暗示应该在有该日期的日期将其显示为“ 19世纪”。
另一种选择是同时使用日期和模糊文本。例如,您可以将其存储为1800-01-01 和 “ 19世纪”,然后基于模糊文本的存在不为空,来确定它实际上不是1800年1月1日。这可以帮助解决前面描述的歧义问题,因为您可以在所有此类情况下都这样做。例如,如果您只知道“ 1880年7月”,则可以将其存储在模糊文本中,并将日期设置为1880-07-01
。然后,基于模糊文本的存在,您可以选择将01
部分解密为基本上为零,而不是按月实际值。如果没有设置模糊文本,则假定它是确切的日期。
至于在模型上表示,我不会使用实际DateTime
属性或DisplayFormat
。拥有可以处理逻辑并返回预格式化的“日期”的实用程序方法会更好地为您服务。然后,您只需做类似的操作@building.GetBuiltDisplay()
,并返回所有已经格式化的信息(包括开始和结束,如果有的话)。
在我最近查看的一个更有趣的项目中,他们以非常有趣的方式做到了:int Century,int?年,datetime2?准确日期。如果知道世纪和/或年份,则确切日期并不重要(可以使用已知数据对其进行大致过滤)。当然,这将占用更多空间,但是比处理诸如1899-12-31这样的任意日期要容易得多。编辑:项目是用于历史项目跟踪的个人收集系统。
@ChrisPratt:“年,月和日-所有可为null的int列。” 为什么不ushort,byte,byte?