Fluent NHibernate / SQL Server 中的版本作为时间戳

发布于 2024-11-04 08:23:19 字数 3005 浏览 1 评论 0 原文

使用 FNH w/ SQL Server 2008,我尝试添加版本作为时间戳,但遇到 SQLDateTime Overflow 错误,因为该值作为 1/1/0001 12:00:00 AM 传递。我发现这个(也引用了此处),但仍然遇到问题。

// entity base
public abstract class EntityBase
{
    public virtual Int64 Id { get; set; }
    public virtual DateTime Version { get; set; }
}

// entity base map
public abstract class EntityBaseMap<T> : ClassMap<T> where T : EntityBase
{
    public EntityBaseMap()
    {
        Id(x => x.Id).GeneratedBy.Identity();
        OptimisticLock.Version();
        Version(x => x.Version)
           .CustomType("Timestamp");

    }
}    

SQL Server 数据类型是“日期时间”。

我猜这是一些小而愚蠢的事情,但还没有找到原因 - 我错过了什么?

编辑:实际“保存”代码的操作方法

    public ActionResult Create()
    {
        int currMaxSortOrder = session.CreateCriteria(typeof(Section))
                            .SetProjection(Projections.ProjectionList().Add(Projections.Max("Sortorder")))
                            .UniqueResult<int>();
        SectionViewModel sectionViewModel = new SectionViewModel();
        sectionViewModel.Sortorder = currMaxSortOrder + 1;
        return View("Create", "_AdminLayout", sectionViewModel);
    }

    [HttpPost]
    public ActionResult Create(SectionViewModel sectionInputModel)
    {
        if (ModelState.IsValid)
        {
            section = new Section();
            Mapper.Map(sectionInputModel, section);
            using (var tx = session.BeginTransaction())
            {
                session.SaveOrUpdate(section);
        tx.Commit();
            }
            return RedirectToAction("index", "pages").WithFlash(new { success = "Section '" + section.Name + "' was successfully added." });
        }
        return View("Create", "_AdminLayout", section);
    }

编辑2:添加了部分实体和内容。映射

    public class Section : EntityBase
    {
        public virtual String Name { get; set; }
        public virtual int Sortorder { get; set; }
        public virtual String RedirectUrl { get; set; }
        public virtual IList<Page> Pages { get; set; }

        public Section()
        {
            Pages = new List<Page>();
        }

        public virtual void AddPage(Page page)
        {
            page.Section = this;
            this.Pages.Add(page);
        }
    }

    public class SectionMap : EntityBaseMap<Section>
    {
        public SectionMap()
        {
            Map(x => x.Name);
            Map(x => x.Sortorder);
            Map(x => x.RedirectUrl);
            // one to many relationship
            HasMany(x => x.Pages)
                .Inverse()
                .Cascade.All();
        }
    }
}

Using FNH w/ SQL Server 2008, I'm trying to add a Version as a timestamp, but running into the SQLDateTime Overflow error because the value is passed as 1/1/0001 12:00:00 AM. I found this (also referenced here), but still experiencing the problem.

// entity base
public abstract class EntityBase
{
    public virtual Int64 Id { get; set; }
    public virtual DateTime Version { get; set; }
}

// entity base map
public abstract class EntityBaseMap<T> : ClassMap<T> where T : EntityBase
{
    public EntityBaseMap()
    {
        Id(x => x.Id).GeneratedBy.Identity();
        OptimisticLock.Version();
        Version(x => x.Version)
           .CustomType("Timestamp");

    }
}    

The SQL Server data type is "datetime".

I'm guessing its something small and stupid, but haven't found the cause yet - what am I missing?

EDIT: Action method for the actual "save" code

    public ActionResult Create()
    {
        int currMaxSortOrder = session.CreateCriteria(typeof(Section))
                            .SetProjection(Projections.ProjectionList().Add(Projections.Max("Sortorder")))
                            .UniqueResult<int>();
        SectionViewModel sectionViewModel = new SectionViewModel();
        sectionViewModel.Sortorder = currMaxSortOrder + 1;
        return View("Create", "_AdminLayout", sectionViewModel);
    }

    [HttpPost]
    public ActionResult Create(SectionViewModel sectionInputModel)
    {
        if (ModelState.IsValid)
        {
            section = new Section();
            Mapper.Map(sectionInputModel, section);
            using (var tx = session.BeginTransaction())
            {
                session.SaveOrUpdate(section);
        tx.Commit();
            }
            return RedirectToAction("index", "pages").WithFlash(new { success = "Section '" + section.Name + "' was successfully added." });
        }
        return View("Create", "_AdminLayout", section);
    }

Edit 2: Added section entity & mapping

    public class Section : EntityBase
    {
        public virtual String Name { get; set; }
        public virtual int Sortorder { get; set; }
        public virtual String RedirectUrl { get; set; }
        public virtual IList<Page> Pages { get; set; }

        public Section()
        {
            Pages = new List<Page>();
        }

        public virtual void AddPage(Page page)
        {
            page.Section = this;
            this.Pages.Add(page);
        }
    }

    public class SectionMap : EntityBaseMap<Section>
    {
        public SectionMap()
        {
            Map(x => x.Name);
            Map(x => x.Sortorder);
            Map(x => x.RedirectUrl);
            // one to many relationship
            HasMany(x => x.Pages)
                .Inverse()
                .Cascade.All();
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

墨落成白 2024-11-11 08:23:19

胆怯啊!时刻

(添加此以防万一像我这样的其他 n00bs 遇到同样的问题)

我终于深入挖掘并意识到我已将其配置为使用 AutoMapping,而我正在创建仅适用于 FluentMapping 的地图。恢复使用 FluentMapping 并且该版本开始完美运行!

我猜我可能会使用 AutoMapping 并添加一个约定,该约定将使用 CustomType("Timestamp") 处理名为“Version”的列,但现在我将使用 FluentMapping 直到我掌握更多速度。

sheepish Doh! moment

(Adding this in case any other n00bs like me run into the same problem)

I finally dug deeper and realized that I had configured it to use AutoMapping while I was creating maps that would only work with FluentMapping. Reverted to use FluentMapping and the Version started working perfectly!

I'm guessing I could possibly use AutoMapping and add a convention that will treat a column named "Version" with CustomType("Timestamp"), but for now am going to use FluentMapping until I get more up to speed.

千柳 2024-11-11 08:23:19

这可能是经典的 .NET min datetime != SQL Server min datetime。

.NET 中的最小日期时间为 0001 年,但在 SQL Server 中,最小日期只能低至 1753 年。 SQL Server 中会出现溢出,因为 SQL 日期时间类型无法存储您要存储的日期。正在努力通过。

您可能对 datetime2 类型有更好的运气,但我不确定与 Hibernate 的兼容性。

有关详细信息,请参阅本文:http://blog.malevy。 net/2010/01/datetimeminvalue-sql-server-minimum.html

This might be the classic .NET min datetime != SQL Server min datetime.

The min datetime in .NET is in the year 0001, but in SQL server the min date can only go as low as the year 1753. You're getting an overflow in SQL Server because the SQL datetime type can't store the date you're trying to pass.

You might have better luck with the datetime2 type, but I'm not sure of the compatibility with Hibernate.

See this article for more info: http://blog.malevy.net/2010/01/datetimeminvalue-sql-server-minimum.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文