2010-03-12 45 views
2

我正在用NHibernate(版本2.1.0.4000)與Fluent NHibernate Automapping進行實驗。實體與Guid ID不是由NHibernate插入

我的測試集的實體仍然存在細微的默認整數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; } 

} 

這裏是流利的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?

謝謝,

丹。

回答

1

您應該檢查你的應用程序(非映射)的代碼,並確保你提交你的NHibernate ITransaction實例。

當使用整數ID和nativeidentity生成器時,NHibernate必須立即插入新實例,以便生成ID值(即使事務尚未提交)。當使用像guid.comb這樣的標識符策略,它不依賴數據庫來生成ID時,NHibernate將不會實際執行插入,直到提交了封閉事務。

+0

解決了! 我並沒有在我的代碼中使用Transaction.Begin()和Transaction.Commit(),並且使用整數ID,一切正常。 在代碼中添加事務使其也可用於GUID。非常感謝, 丹。 – DanK 2010-03-14 20:16:41

0

我對自動映射的情況並不完全確定。

但是,我可以告訴你的一件事是,當你構建它們而不是Guid.NewGuid()時,確保將你的類的新實例的Guid設置爲Guid.Empty。這向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); 
     ... 
    } 
}