【问题标题】:Entity with Guid ID is not inserted by NHibernateNHibernate 未插入具有 Guid ID 的实体
【发布时间】:2010-03-12 17:08:28
【问题描述】:

我正在使用 Fluent NHibernate Automapping 试验 NHibernate(版本 2.1.0.4000)。

我的实体测试集使用默认整数 ID 保持正常

我现在正在尝试对实体使用 Guid ID。不幸的是,将 Id 属性更改为 Guid 似乎会阻止 NHibernate 插入对象。

这里是实体类:

public class User
{
    public virtual int Id { get; private set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual string Email { get; set; }
    public virtual string Password { get; set; }

    public virtual List<UserGroup> Groups { get; set; }

}

这是我正在使用的 Fluent NHibernate 配置:

        SessionFactory = Fluently.Configure()
                            //.Database(SQLiteConfiguration.Standard.InMemory)
                            .Database(MsSqlConfiguration.MsSql2008.ConnectionString(@"Data Source=.\SQLEXPRESS;Initial Catalog=NHibernateTest;Uid=NHibernateTest;Password=password").ShowSql())
                            .Mappings(m =>
                                m.AutoMappings.Add(
                                    AutoMap.AssemblyOf<TestEntities.User>()
                                            .UseOverridesFromAssemblyOf<UserGroupMappingOverride>()))
                            .ExposeConfiguration(x =>
                                {
                                    x.SetProperty("current_session_context_class","web");
                                })
                            .ExposeConfiguration(Cfg => _configuration = Cfg)
                            .BuildSessionFactory();

这是使用整数 ID 时的日志输出:

16:23:14.287 [4] DEBUG NHibernate.Event.Default.DefaultSaveOrUpdateEventListener - saving transient instance
16:23:14.291 [4] DEBUG NHibernate.Event.Default.AbstractSaveEventListener - saving [TestEntities.User#<null>]
16:23:14.299 [4] DEBUG NHibernate.Event.Default.AbstractSaveEventListener - executing insertions
16:23:14.309 [4] DEBUG NHibernate.Event.Default.AbstractSaveEventListener - executing identity-insert immediately
16:23:14.313 [4] DEBUG NHibernate.Persister.Entity.AbstractEntityPersister - Inserting entity: TestEntities.User (native id)
16:23:14.321 [4] DEBUG NHibernate.AdoNet.AbstractBatcher - Opened new IDbCommand, open IDbCommands: 1
16:23:14.321 [4] DEBUG NHibernate.AdoNet.AbstractBatcher - Building an IDbCommand object for the SqlString: INSERT INTO [User] (FirstName, LastName, Email, Password) VALUES (?, ?, ?, ?); select SCOPE_IDENTITY()
16:23:14.322 [4] DEBUG NHibernate.Persister.Entity.AbstractEntityPersister - Dehydrating entity: [TestEntities.User#<null>]
16:23:14.323 [4] DEBUG NHibernate.Type.StringType - binding null to parameter: 0
16:23:14.323 [4] DEBUG NHibernate.Type.StringType - binding null to parameter: 1
16:23:14.323 [4] DEBUG NHibernate.Type.StringType - binding 'ertr' to parameter: 2
16:23:14.324 [4] DEBUG NHibernate.Type.StringType - binding 'tretret' to parameter: 3
16:23:14.329 [4] DEBUG NHibernate.SQL - INSERT INTO [User] (FirstName, LastName, Email, Password) VALUES (@p0, @p1, @p2, @p3); select SCOPE_IDENTITY();@p0 = NULL, @p1 = NULL, @p2 = 'ertr', @p3 = 'tretret'

这是使用 Guid 时的输出:

16:50:14.008 [4] DEBUG NHibernate.Event.Default.DefaultSaveOrUpdateEventListener - saving transient instance
16:50:14.012 [4] DEBUG NHibernate.Event.Default.AbstractSaveEventListener - generated identifier: d74e1bd3-1c01-46c8-996c-9d370115780d, using strategy: NHibernate.Id.GuidCombGenerator
16:50:14.013 [4] DEBUG NHibernate.Event.Default.AbstractSaveEventListener - saving [TestEntities.User#d74e1bd3-1c01-46c8-996c-9d370115780d]

这是它静默失败的地方,没有抛出异常或进一步的日志条目。

看起来它正在为新对象正确生成 Guid ID,但并没有比这更进一步。

为了使用 Guid ID,我需要做些不同的事情吗?

谢谢,

丹。

【问题讨论】:

    标签: nhibernate fluent-nhibernate


    【解决方案1】:

    您应该检查您的应用程序(非映射)代码,并确保您正在提交您的 NHibernate ITransaction 实例。

    当使用整数 ID 和 native 或 identity 生成器时,NHibernate 必须立即插入新实例以便生成 ID 值(即使尚未提交事务)。当使用像 guid.comb 这样不依赖数据库生成 ID 的标识符策略时,NHibernate 在提交封闭事务之前不会实际执行插入。

    【讨论】:

    • 解决了!我根本没有在我的代码周围使用 Transaction.Begin() 和 Transaction.Commit(),并且使用整数 ID,一切正常。在代码周围添加事务使其也可以与 GUID 一起使用。非常感谢,丹。
    【解决方案2】:

    我不完全确定自动映射的情况。

    但是,我可以告诉您的一件事是,当您构造类的新实例时,务必将 Guid 设置为 Guid.Empty,而不是 Guid.NewGuid()。这向 NHibernate 发出信号,表明该对象是新的,应该插入而不是更新;与 int 属性的零非常相似。 NHibernate 会在插入时将属性更新为生成的 Guid。

    公共课猫 { 公共猫() : 根据() { this.Id = Guid.Empty; } 公共虚拟 Guid Id { 获取;放; } ... }

    在手动映射情况下,地图如下所示:

    公共类 CatMap : ClassMap { 公共猫图() : 根据() { this.Id(e => e.Id); ... } }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-09
      • 2020-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多