【问题标题】:Version as timestamp in Fluent NHibernate / SQL ServerFluent NHibernate / SQL Server 中作为时间戳的版本
【发布时间】:2011-04-29 23:58:39
【问题描述】:

使用带有 SQL Server 2008 的 FNH,我尝试将版本添加为时间戳,但遇到 SQLDateTime 溢出错误,因为该值作为 1/1/0001 12:00:00 AM 传递。我找到了this(也引用了here),但仍然遇到问题。

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

【问题讨论】:

  • 拜托,你能添加一个导致错误的代码片段吗?
  • @Jakub,在上面添加了代码片段。谢谢。
  • 嗯,类似的情况对我很有效。您是否使用任何侦听器或拦截器? Section 实体及其映射如何?是时间戳分贝。列不为空?
  • @Jakob,没有监听器或拦截器,但使用 Castle Windsor,如图所示here。上面添加了部分实体和映射。尝试将 DB 数据类型 datetime 作为“null”和“not null”。

标签: sql-server asp.net-mvc fluent-nhibernate version


【解决方案1】:

愚蠢的Doh!时刻

(添加这个以防像我这样的其他 n00b 遇到同样的问题)

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

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

【讨论】:

    【解决方案2】:

    这可能是经典的 .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

    【讨论】:

    • 是的 - 也尝试过,即将 SQL 数据类型更改为 datetime2(7) 并将地图更改为使用 CustomType("datetime2") - 没有区别
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 2010-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多