使用LINQtoSQL超出范围的Datetime问题

时间:2010-05-06 14:10:49

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

这让我很困惑。这是我模型的片段:

* 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()
                     });

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

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

我错过了一些基本的东西吗?提前谢谢!

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

4 个答案:

答案 0 :(得分:3)

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

如果你使用Nullable<DateTime>,那么sql会对它会得到的null感到满意。

答案 1 :(得分:1)

也许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 ...

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

问题出在.fade-enter-active, .fade-leave-active { transition: opacity 2s; } .fade-enter, .fade-leave-to { opacity: 0; } .fade-enter-to, .fade-leave { opacity: 1; } 调用上。 LINQ to SQL(有点愚蠢的IMO)通过使用GetValueOrDefault()子句(类似于COALESCE)将其转换为真实的SQL,如下所示:

ISNULL

不幸的是,SQL Server COALESCE(LastModified, '1/1/0001 12:00:00 AM') 数据类型不接受大约1753年之前的日期。因此SQL Server将错误回传给LINQ to SQL,这又将错误回传给您。

如果使用Nullable,则SQL Server会对它将获得的null感到满意。但是,如果您仍然想使用datetime,例如在用于过滤结果的查询中,您有两种选择:

  1. GetValueOrDefault()
  2. LastModified.GetValueOrDefault(System.Data.SqlTypes.SqlDateTime.MinValue.Value)