C#/EF 核心:使用(历史)dates/periods
C#/EF Core: Working with (historical) dates/periods
给定一个使用 ASP.NET 核心 Mvc 使用 SQL 服务器和 EF 核心的 C# 网站。
对于业余爱好项目,我正在查找旧报纸、文件并搜索特定建筑物。每次我找到此类建筑物的信息时,我都会尝试记下日期信息。这样我就可以知道这座建筑是在哪个时期存在的。
假设我遇到了 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 世纪以来的所有内容。
关于最后一个问题,我的意思是,如果建筑物只有一个日期(例如 1835 年),您将如何编写 linq 查询。如果只给出一个日期,每个查询是否会包含对可空日期的额外检查?还是有更好的方案?
.Where(x => x.Date1 != null && x.Date1 >= 1830 && (x.Date2 == null || x.Date2 <= 1930))
或者正在保存日期时间? object 不是一个好主意,最好存储一个短整数或整数并且只跟踪年份部分(如果有的话)?
真的,您的问题归结为显示确切日期与 "fuzzy" 日期。没有单一的策略,但我之前有过类似的要求,并通过开始日期、模糊开始、结束日期和模糊结束来处理它,所有这些都可以为空。
如果您完全知道日期的任何确切部分,则可以使用实际的日期时间字段。例如,如果您只知道 1880,则将其存储为 1880-01-01
。如果您知道年份和月份,则只需将日期设为 01
,当然,如果您知道完整的日期,则可以存储它。现在,当然,这可能会带来问题。你怎么知道它不是字面意义上的 1880 年 1 月 1 日建造的,而是一般意义上的 1880 年建造的?好吧,这取决于您决定如何处理这些情况。您可以假设任何 01
与该日期部分的空值相同。无论出于何种原因,建筑物一般不会在 1 月 1 日或任何一个月的 1 日开放,但总会有例外。
如果您确实需要更高的精度,您可能需要将日期分开并将其按字面意义存储为年、月和日 - 所有可为空的 int 列。然后,您可以简单地将它拼凑在一起,但需要展示它时,您可以随心所欲地拼凑起来。
"fuzzy" 日期列将是字符串,您可以在其中存储更多星云 "dates",例如 "Victorian Era",即您可能没有真实的日期甚至年份,但是你知道那是在某个时期。你可以对“19 世纪”之类的东西做同样的事情,但我个人更喜欢将其存储为 1800-01-01,然后直觉认为当有这种形式的日期时它应该显示为“19 世纪”。
另一种选择是同时使用日期和模糊文本。例如,您可以将其存储为 1800-01-01 and“19 世纪”,然后您可以根据是否存在模糊文本不为空。这有助于解决前面描述的歧义问题,因为您可以对所有此类情况执行此操作。例如,如果您只知道 "July 1880",那么您可以将其存储在模糊文本中,并将日期设置为 1880-07-01
。然后,根据模糊文本的存在,您可以选择将 01
部分解读为本质上为空,而不是字面上的第一个月。如果没有模糊文本集,那么您会认为它是一个确切的日期。
就在您的模型上表示它而言,我不会使用实际的 DateTime
属性或 DisplayFormat
。拥有可以处理逻辑和 return a pre-formatted "date" 的实用方法会更好地为您服务。然后,您只需执行 @building.GetBuiltDisplay()
之类的操作,并且 return 您知道的所有信息(包括开始和结束,如果有的话)已经格式化。
给定一个使用 ASP.NET 核心 Mvc 使用 SQL 服务器和 EF 核心的 C# 网站。
对于业余爱好项目,我正在查找旧报纸、文件并搜索特定建筑物。每次我找到此类建筑物的信息时,我都会尝试记下日期信息。这样我就可以知道这座建筑是在哪个时期存在的。
假设我遇到了 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 世纪以来的所有内容。
关于最后一个问题,我的意思是,如果建筑物只有一个日期(例如 1835 年),您将如何编写 linq 查询。如果只给出一个日期,每个查询是否会包含对可空日期的额外检查?还是有更好的方案?
.Where(x => x.Date1 != null && x.Date1 >= 1830 && (x.Date2 == null || x.Date2 <= 1930))
或者正在保存日期时间? object 不是一个好主意,最好存储一个短整数或整数并且只跟踪年份部分(如果有的话)?
真的,您的问题归结为显示确切日期与 "fuzzy" 日期。没有单一的策略,但我之前有过类似的要求,并通过开始日期、模糊开始、结束日期和模糊结束来处理它,所有这些都可以为空。
如果您完全知道日期的任何确切部分,则可以使用实际的日期时间字段。例如,如果您只知道 1880,则将其存储为 1880-01-01
。如果您知道年份和月份,则只需将日期设为 01
,当然,如果您知道完整的日期,则可以存储它。现在,当然,这可能会带来问题。你怎么知道它不是字面意义上的 1880 年 1 月 1 日建造的,而是一般意义上的 1880 年建造的?好吧,这取决于您决定如何处理这些情况。您可以假设任何 01
与该日期部分的空值相同。无论出于何种原因,建筑物一般不会在 1 月 1 日或任何一个月的 1 日开放,但总会有例外。
如果您确实需要更高的精度,您可能需要将日期分开并将其按字面意义存储为年、月和日 - 所有可为空的 int 列。然后,您可以简单地将它拼凑在一起,但需要展示它时,您可以随心所欲地拼凑起来。
"fuzzy" 日期列将是字符串,您可以在其中存储更多星云 "dates",例如 "Victorian Era",即您可能没有真实的日期甚至年份,但是你知道那是在某个时期。你可以对“19 世纪”之类的东西做同样的事情,但我个人更喜欢将其存储为 1800-01-01,然后直觉认为当有这种形式的日期时它应该显示为“19 世纪”。
另一种选择是同时使用日期和模糊文本。例如,您可以将其存储为 1800-01-01 and“19 世纪”,然后您可以根据是否存在模糊文本不为空。这有助于解决前面描述的歧义问题,因为您可以对所有此类情况执行此操作。例如,如果您只知道 "July 1880",那么您可以将其存储在模糊文本中,并将日期设置为 1880-07-01
。然后,根据模糊文本的存在,您可以选择将 01
部分解读为本质上为空,而不是字面上的第一个月。如果没有模糊文本集,那么您会认为它是一个确切的日期。
就在您的模型上表示它而言,我不会使用实际的 DateTime
属性或 DisplayFormat
。拥有可以处理逻辑和 return a pre-formatted "date" 的实用方法会更好地为您服务。然后,您只需执行 @building.GetBuiltDisplay()
之类的操作,并且 return 您知道的所有信息(包括开始和结束,如果有的话)已经格式化。