如何在DB和ORM中设计出生日期,以便混合已知和未知的日期部分

Jer*_*oen 11 c# sql-server asp.net orm date-of-birth

请注意,我的问题与SO 1668172类似.


这是一个设计问题,以前肯定必须出现在其他人身上,但我找不到适合我情况的答案.我想在我的应用程序中记录出生日期,其中有几个"级别"的信息:

  • NULL 价值,即DoB未知
  • 1950-??-?? 只知道DoB年份值,日期/月份不是
  • ????-11-23 只需一个月,一天,或两者的组合,但没有一年
  • 1950-11-23 完整的DoB是众所周知的

我用于我的应用程序的技术如下:

  • Asp.NET 4(C#),可能与MVC
  • 一些ORM解决方案,可能是Linq-to-sql或NHibernate的
  • MSSQL Server 2008,起初只是Express版

到目前为止,我想到了SQL位的可能性:

  • 1)使用一个可空的varchar列,例如1950-11-23,并用'X'代替unkowns,例如XXXX-11-231950-XX-XX
  • 2)采用下列三种可空INT列如1950,1123
  • 3)使用年份的INT列,以及完整已知DoB的日期时间列

对于这个问题的C#结尾,我只想看到这两个选项:

  • A)使用字符串属性来表示DoB,仅用于视图目的.
  • B)为DoB使用自定义(?)结构或类,具有三个可空整数
  • C)使用可空的DateTime和可以为空的整数

解决方案似乎在1A,2B3C处形成匹配对.当然1A不是一个很好的解决方案,但它确实设置了基线.

任何提示和链接都非常感谢.好吧,如果他们有关系,无论如何:)


编辑,关于答案:我将一个答案标记为已接受,因为我认为它对我有用.不过,如果你在这里遇到同样的问题,也值得一看其他答案.

Eri*_*ikE 3

SQL 端

我关于这个主题的最新想法是使用不确定或可能具有不同特异性的日期范围。给定两列:

DobFromDate (inclusive)
DobToDate (exclusive)
Run Code Online (Sandbox Code Playgroud)

以下是它如何适用于您的场景:

Specificity   DobFromDate   DobToDate
-----------   -----------   ----------
YMD            2006-05-05   2006-05-06
YM             2006-05-01   2006-06-01
Y              2006-01-01   2007-01-01
Unknown        0000-01-01   9999-12-31
-> MD, M, D not supported with this scheme
Run Code Online (Sandbox Code Playgroud)

请注意,没有理由不能将其一直传递到小时、分钟、秒、毫秒等。

然后当查询特定日期出生的人时:

DECLARE @BornOnDay date = '2006-05-16'

-- Include lower specificity:
SELECT *
FROM TheTable
WHERE
   DobFromDate <= @BornOnDay
   AND @BornOnDay < DobToDate;

-- Exclude lower specificity:
SELECT *
FROM TheTable
WHERE
   DobFromDate = @BornOnDay
   AND DobToDate = DateAdd(Day, 1, @BornOnDay);
Run Code Online (Sandbox Code Playgroud)

对我来说,它具有可维护性、易用性和表现力的最佳组合。它不会处理更重要的值的精度损失(例如,您知道月份和日期,但不知道年份),但如果可以解决这个问题,那么我认为它是赢家。

如果您要按日期查询,那么一般来说,更好的解决方案(在我看来)将以某种方式将项目保留为服务器上的日期。

另请注意,如果您正在寻找日期范围而不是一天,则使用我的解决方案,您仍然只需要两个条件,而不是四个:

DECLARE
   @FromBornOnDay date = '2006-05-16',
   @ToBornOnDay date = '2006-05-23';

-- Include lower specificity:
SELECT *
FROM TheTable
WHERE
   DobFromDate < @ToBornOnDay
   AND @FromBornOnDay < DobToDate;
Run Code Online (Sandbox Code Playgroud)

C# 方面

我将使用一个自定义类,其中包含对其进行适当的日期数学和日期比较所需的所有方法。您了解如何使用未知日期的业务需求,并且可以对类中的逻辑进行编码。如果您在某个日期之前需要某些东西,您会只使用已知的还是未知的物品?会返回什么ToString()?在我看来,这些问题最好通过课堂来解决。