NHibernate Sqldatetime必须介于1/1/1753和12/31/9999之间。

4

我在我的MVC项目中使用NHibernate。我的问题是,在尝试更新对象时,我遇到了以下错误。

SqlDateTime溢出。必须介于1/1/1753 12:00:00 AM和12/31/9999 11:59:59 PM之间。

在调试模式下,我看到日期属性不为空。我在映射上设置了Datetime可空。但我仍然收到sqldatetime错误。

public class EntityBaseMap<T> : ClassMap<T> where T : EntityBase
{
    public EntityBaseMap()
    {
        Id(x => x.Id).GeneratedBy.Identity();
        Map(x => x.IsDeleted).Not.Nullable();
        Map(x => x.CreatedAt).Nullable();
        Map(x => x.UpdatedAt).Nullable();
        Map(x => x.Random).Formula("NEWID()");

        References(x => x.Status).Column("StatusId");

        Where("IsDeleted=0");
    }
}

保存时,日期时间属性不为空。

public int SaveOrUpdatePage(PageDto PageDto)
{
    var page = PageDto.Id > 0 ? ById<Page>(PageDto.Id) : new Page();
    var status = PageDto.Status.Id > 0 ? LookupById<Status>(PageDto.Status.Id) : null;
    var type = PageDto.Type.Id > 0 ? LookupById<PageType>(PageDto.Type.Id) : null;
    //var parent = PageDto.Parent.Id > 0 ? ById<Page>(PageDto.Parent.Id) : page.Parent;

    page.Description = PageDto.Description;
    page.Title = PageDto.Title;
    page.SpotText = PageDto.SpotText;
    page.Status = status;
    page.Text = PageDto.Text;
    page.Url = !string.IsNullOrEmpty(PageDto.Url) ? PageDto.Url.ToFileName() : PageDto.Title.ToFileName();
    page.Featured = PageDto.Featured;
    page.Type = type;

    using (var tran = UnitOfWork.CurrentSession.BeginTransaction())
    {
        UnitOfWork.CurrentSession.SaveOrUpdate(page);
        tran.Commit();
    }


    page.CreateDirectory();

    if (PageDto.Id == 0)
    {
        page.Copy();
        page.CopyThumbs();
    }

    SetResultAsSuccess();

    return page.Id;
}

我正在使用SQLServer 2008,并在表中使用允许为空的日期时间列。

PagePageDto 中,DateTime 可以为 null 吗? - Jay
1个回答

7

这不是关于NULL可空列的问题,而是关于C#中DateTime值类型的默认值的问题。

default(DateTime) == new DateTime(1,1,1) // 1st January of year 1 

所以,因为CreatedAt或UpdatedAt被定义为...
public virtual DateTime CreatedAt { get; set; }
public virtual DateTime UpdatedAt { get; set; }

永远不要将日期时间值设置为默认值,其值为1.1.0001。这个值比SQL Server的下限1.1.1753还要小...

换句话说,请确保将这些值设置为有意义的值,例如DateTime.Now


您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - erkan demir
3
可能是......但是问题肯定不在同一列上。简单地说,几乎总是(99.98%的情况下),这个问题的意思是:存在一个DateTime属性而非DateTime?。这种属性没有设置自定义值,只是保留默认值1.1.0001。仔细检查异常(你会看到哪一列有问题),然后你肯定会发现它的值(在调试中)被保留为default(DateTime)...希望能有所帮助。 - Radim Köhler
是的,这很有帮助。有没有办法在保存时找到错误格式的记录? - erkan demir
是的。测试/单元测试。我尽力保持所有(真的几乎所有)实体都在基本的CRUD测试下,以确保它们通过映射到数据库。如果这些测试失败,将会得到具有非常描述性信息的完整堆栈异常。NHibernate确实拥有出色的异常系统。只需观察完整的堆栈,您就会看到清晰的答案...换句话说,我建议创建自己的测试并开始从“可持续和可维护”的开发中获益-由测试驱动。我很认真,这是我找到的唯一方法...除了短期之外还有其他方法吗? - Radim Köhler
很好的回答Radim。另一个选项是在数据库上设置默认日期,这样你就不需要记得在c#中设置它们。当我需要记住这些类型的事情时,我总是会忘记! - Rippo
@Rippo 正确!很好,缺省值是有原因的,是个好解决方案 ;) - Radim Köhler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接