我正在尝试设置从用户到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生成null id。”
如果有人能告诉我我做错了什么,我真的很感激。感谢
编辑:感谢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()添加到我的Reference上,我会收到原始错误,我得到的是关于生成的null id。
答案 0 :(得分: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();
}
}
编辑:
请参阅this和this。您似乎必须将用户方面的关系映射为多对一关系,并从UserDetails端进行一对一约束,以便一对一地进行延迟加载。我不知道NH3是否有所不同。
答案 1 :(得分:0)
我不确定您映射ID属性的方式是否正确。它不应该是一个自动增加的id,你的映射应该如下:
Id(x=>x.UserId);
我不知道使用外国背后的想法以及它如何适应这里的事情..你能否说明背后的逻辑?
答案 2 :(得分:0)
我认为您需要在User映射中使用外键标识映射,而不是在UserDetails中使用UserDetails和本地映射。不过,我一直无法找到它的参考。
答案 3 :(得分: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);
答案 4 :(得分:0)
经过进一步研究后,似乎在2.0版本中无法使用。我现在可以升级到版本3.0,我相信现在可以使用。