【问题标题】:Out-of-range Datetime issue using LINQtoSQL使用 LINQtoSQL 的超出范围的日期时间问题
【发布时间】:2011-02-16 10:10:12
【问题描述】:

这是我的模型的 sn-p:

* SQL Server *

Event
-----
Id (int, PK) NOT NULL
Title (varchar(100)) NULL
LastModified (datetime) NULL

EventDates
----------
Id (int, PK) NOT NULL
StartDate (datetime) NULL
EndDate (datetime) NULL

* C# *

Event
-----
public int Id
public string Title
public DateTime LastModified

EventDates
----------
public int Id
public DateTime StartDate
public Datetime EndDate

LastModified 字段自创建以来一直在数据库中。我在保存事件时一直在保存它的值,但我想在表格中显示它,所以我更改了我的事件存储库 GetEvents 的返回值:

return (from e in GetDbEvents()
                select new Event
                {
                    // Miscellaneous fields..
                    LastModified = e.LastModified.GetValueOrDefault() // Shiny new code
                });

当我现在打电话时,我会被骂:

The conversion of a char data type to a datetime data type 
resulted in an out-of-range datetime value.

如果我将上面的代码去掉,它仍然没有帮助,如果我尝试枚举结果,我会得到同样的错误:

var test = (from e in _db.Events
                    select e.LastModified.GetValueOrDefault());

作为测试,我对 EventDates 表做了同样的声明(同样,有 2 个日期时间列):

 var test4 = (from ed in _db.EventDates
                     select new EventDate
                     {
                         StartDate = ed.StartDate.GetValueOrDefault(),
                         EndDate = ed.EndDate.GetValueOrDefault()
                     });

当然,这很好用。我枚举时没有错误,所有值都是正确的。

我应该指出Events 表中的一些LastModified 值是NULL,而EventDates 中的所有值都填充了数据。

编辑

我的主要问题是为什么Events 给我超出范围的问题而EventDates 没有,即使模型非常相似?

【问题讨论】:

  • 您正在检查的每个表格列中日期的最小值和最大值(即 MIN() 和 MAX())是多少?

标签: asp.net sql-server linq-to-sql sql-server-2000


【解决方案1】:

如果您将 C# 变量 LastModified 的声明更改为 public DateTime? LastModified,这应该可以解决您的问题。加上问号表示它是可以为空的类型。

【讨论】:

  • 我会试一试。然而,我的主要问题是——Events 怎么会出现这个问题而不是 EventDates?谢谢!
【解决方案2】:

也许this 是相关的?

一种可能的解决方法(如果您不想将 LastModified 更改为 DateTime?,则要求您在代码中到处乱扔.Value..) 是从数据库为DateTime?,但在您的代码中将它们转换为DateTime。例如:

return from e in GetDbEvents()
       select new Event(e.LastModified);

...

//In Event class:
public Event(DateTime? lastModified)
{
    LastModified = lastModified.GetValueOrDefault();
}

这将导致 GetValueOrDefault() 被称为客户端,而不是 SQL 的一部分。

请注意,这种方法确实有problems of its own...

【讨论】:

  • 感谢您的链接!我喜欢这个错误是“无法修复”的——它只是为我的“升级到 2008”战斗提供了更多弹药:P
【解决方案3】:

问题在于 GetValueOrDefault()。这将在“默认”情况下返回 DateTime.MinValue (01-01-0001) 并且 sqlserver 不接受(它拒绝大约 1753 年之前的日期)。

如果你使用Nullable<DateTime>,那么 sql 会很高兴得到null

【讨论】:

    【解决方案4】:

    扩展Hans Kesting's answer,并帮助在过滤/WHERE 子句而不是 SELECT 子句中遇到此问题的人:

    问题在于GetValueOrDefault() 调用。 LINQ to SQL(有点愚蠢的 IMO)通过使用 COALESCE 子句(类似于 ISNULL)将其转换为真正的 SQL,如下所示:

    COALESCE(LastModified, '1/1/0001 12:00:00 AM')
    

    不幸的是,SQL Server datetime 数据类型不接受大约 1753 年之前的日期。因此,SQL Server 将错误返回给 LINQ to SQL,然后再返回给您。

    如果你使用 Nullable,那么 SQL Server 会很高兴它会得到 null。但是如果你仍然想使用GetValueOrDefault(),例如在过滤结果的查询中,您有几个选项:

    1. LastModified.GetValueOrDefault(System.Data.SqlTypes.SqlDateTime.MinValue.Value)
    2. LastModified.HasValue && LastModified > DateTime.Now

    【讨论】:

      猜你喜欢
      • 2019-02-20
      • 1970-01-01
      • 1970-01-01
      • 2017-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多