我正在使用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,我需要做些什么吗?
谢谢,
丹
答案 0 :(得分:1)
您应该检查您的应用程序(非映射)代码,并确保您提交了NHibernate ITransaction
实例。
当使用整数ID和native
或identity
生成器时,NHibernate必须立即插入一个新实例,以便生成ID值(即使事务尚未提交)。当使用不依赖于数据库生成ID的guid.comb
之类的标识符策略时,NHibernate在提交封闭事务之前不会实际执行插入。
答案 1 :(得分:0)
我不完全确定自动映射情况。
但是,我可以告诉你的一件事是确保在构造类的Guid.Empty时将Guid安装在Guid.Empty的新实例上,而不是Guid.NewGuid()。这向NHibernate发出信号,表示该对象是新的,应该插入而不是更新;与int属性的零相同。 NHibernate会在插入时将属性反向更新为生成的Guid。
public class Cat { public Cat() : base() { this.Id = Guid.Empty; } public virtual Guid Id { get; set; } ... }
在手动映射情况下,地图将如下所示:
public class CatMap : ClassMap { public CatMap() : base() { this.Id(e => e.Id); ... } }