映射一对一关系不允许插入

时间:2011-01-11 16:50:35

标签: nhibernate fluent-nhibernate one-to-one

我正在尝试设置从用户到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。

5 个答案:

答案 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();
    }
}

编辑:

请参阅thisthis。您似乎必须将用户方面的关系映射为多对一关系,并从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,我相信现在可以使用。