2011-01-11 50 views
2

我試圖設置從我的用戶到UserDetails表的一對一映射。說我有我的數據庫中下表:地圖一對一關係不允許插入

Users: 

- UserID (PK, Identity) 
- UserName 
- Password 

UsersDetails: 

- UserID (PK, FK) 
- FirstName 
- LastName 

我創建了以下POCO類:

public class User { 
    public virtual int UserID { get; set; } 
    public virtual string UserName { get; set; } 
    public virtual string Password { get; set; } 
    public virtual UserDetails Details { get; set; } 
} 

public class UserDetails { 
    public virtual int UserID { get; set; } 
    public virtual User User { get; set; } 
    public virtual string FirstName { get; set; } 
    public virtual string LastName { get; set; } 

    public UserDetails() { 
    } 

    public UserDetails(User user) { 
     User = user; 
    } 
} 

哪些是流利映射(請注意XML映射非常相似,如果你知道是XML映射然後我還是會感謝你的指導):

public class UserMap : ClassMap<User> { 
    public UserMap() { 
     Table("Users"); 
     Id(x => x.UserID); 
     Map(x => x.UserName); 
     Map(x => x.Password); 
     HasOne(x => x.Details) 
      .Constrained() 
      .Cascade.All(); 
    } 
} 

public class UserDetailsMap : ClassMap<UserDetails> { 
    public UserDetailsMap() { 
     Table("UsersDetails"); 
     Id(x => x.UserID) 
      .GeneratedBy.Foreign("User"); 
     HasOne(x => x.User) 
      .Constrained(); 
     Map(x => x.FirstName); 
     Map(x => x.LastName); 
    } 
} 

一切顯示正常,但如果我說:

var user = new User() { UserName = "Test", Password = "Test" }; 
user.Details = new UserDetails(user) { FirstName = "Test", LastName = "Test" }; 
session.Save(user); 

我得到的錯誤:

「NHibernate.Id.IdentifierGenerationException:用於生成空ID:的UserDetails」

我真的很感激,如果有人能告訴我我做錯了什麼。謝謝

編輯:感謝Jamie Ide的建議。我已經改變了我的用戶映射到:

public class UserMap : ClassMap<User> { 
    public UserMap() { 
     Table("Users"); 
     Id(x => x.UserID); 
     Map(x => x.UserName); 
     Map(x => x.Password); 
     References(x => x.Details, "UserID") 
      .Class<UserDetails>() 
      .Unique(); 
    } 
} 

但現在當我插入一個用戶我得到的錯誤:

「System.ArgumentOutOfRangeException:索引超出範圍必須爲非負值並小於。集合的大小「。

如果我添加Cascade.All()到我的參考我收到原始錯誤我得到關於生成的空id。

回答

0

經過進一步研究看來,這不會在2.0版本。我現在可以升級到3.0版本,我相信現在可以這樣做了。

0

我不確定你是如何映射ID屬性是正確的。不應該只是將自動遞增的ID和你的映射應如下:

Id(x=>x.UserId); 

我不知道後面利用外資的理念,如何適應這裏的東西..可以請你說明背後的邏輯是什麼?

+0

乾杯,但UsersDetails表中的UserID字段是對包含自動遞增ID的Users表的引用。由於它是一對一映射,因此UsersDetails表中的用戶標識也是主鍵。希望有所幫助。 – nfplee 2011-01-11 19:26:59

0

我認爲你需要在User映射中擁有外鍵標識映射,而不是UserDetails中的外鍵標識映射,而在UserDetails中則需要有本地映射。不過,我一直無法找到它的參考。

+0

感謝您的回覆。我剛剛發現了以下文章(http://nhforge.org/blogs/nhibernate/archive/2011/01/08/composite-with-only-a-many-to-one-bad-idea.aspx) NHibernate博客。這是我想要達到的效果,但我仍然無法看到我的映射有什麼不同。 – nfplee 2011-01-11 22:53:06

2

我認爲Constrained應該只在UserDetailsMap中指定,而不是在UserMap中指定。嘗試:

public class UserMap : ClassMap<User> { 
    public UserMap() { 
     Table("Users"); 
     Id(x => x.UserID); 
     Map(x => x.UserName); 
     Map(x => x.Password); 
     HasOne(x => x.Details) 
      .Cascade.All(); 
    } 
} 

編輯:

thisthis。看起來您必須將關係映射爲來自用戶端的多對一和來自UserDetails端的一對一約束,以獲得一對一工作的延遲加載。我不知道這在NH3中是否有所不同。

+0

如果您沒有指定一對一關係的約束,則不支持延遲加載。 – nfplee 2011-01-12 08:48:30

0

http://gorbach.wordpress.com/2010/09/24/fluent-onetoone/

HasOne(x => x.Details).Cascade.All().ForeignKey("UserDetails"); 
HasOne(x => x.User).Constrained(); 
var user = new User() { UserName = "Test", Password = "Test" }; 
user.Details = new UserDetails(user) { FirstName = "Test", LastName = "Test" }; 
user.Details.User = user; 
session.Save(user); 
相關問題