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

发布于 2024-10-11 04:17:40 字数 2360 浏览 7 评论 0原文

我正在尝试设置从用户到 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:为 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() 添加到我的参考中,我会收到关于生成的 null id 的原始错误。

I'm trying to setup a one-to-one mapping from my Users to the UserDetails table. Say I have the following tables in my database:

Users:

- UserID (PK, Identity)
- UserName
- Password

UsersDetails:

- UserID (PK, FK)
- FirstName
- LastName

I have created the following poco classes:

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;
    }
}

Which are fluently mapped (please note the xml mapping is very similar and if all you know is the xml mapping then I would still appreciate you guidance):

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);
    }
}

Everything displays correctly but if I say:

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

I get the error:

"NHibernate.Id.IdentifierGenerationException: null id generated for: UserDetails."

I'd really appreciate it if someone could show me what I've done wrong. Thanks

Edit: Courtesy of Jamie Ide's suggestion. I have changed my User mapping to:

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

But now when i insert a user i get the error:

"System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection."

If i add Cascade.All() on to my Reference i receive the original error i was getting about the null id generated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

黎歌 2024-10-18 04:17:40

我认为 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();
    }
}

编辑:

请参阅这个。看来您必须将关系映射为来自用户端的多对一关系和来自用户详细信息端的一对一约束关系,才能实现一对一的延迟加载。我不知道NH3是否有不同。

I think Constrained should only be specified in the UserDetailsMap, not in the UserMap. Try:

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

EDIT:

See this and this. It appears that you have to map the relationship as many-to-one from the User side and one-to-one constrained from the UserDetails side to get lazy loading working with one-to-one. I don't know if this is different in NH3.

梦旅人picnic 2024-10-18 04:17:40

我不确定您映射 ID 属性的方式是否正确。它不应该只是一个自动递增的id,并且您的映射应该如下所示:

Id(x=>x.UserId);

我不知道使用Foreign背后的想法以及它如何适应这里的事物..您能说明一下其背后的逻辑吗?

I am not sure the way you are mapping the ID property is correct. shouldnt it just be an autoincremented id and your mapping should be as follows:

Id(x=>x.UserId);

I dont know the idea behind using Foreign and how it fits into things here.. can you please illustrate the logic behind that?

痴意少年 2024-10-18 04:17:40

我认为您需要在用户映射中使用外键身份映射,而不是在 UserDetails 和 UserDetails 中使用本机身份映射。不过,我一直无法找到它的参考。

I think you need to have the foreign key identity mapping in your User mapping instead of the UserDetails and the native one in the UserDetails. I have been unable to find a reference for it, though.

落墨 2024-10-18 04:17:40

http://gorbach.wordpress.com/2010/09/24/ Fluent-一对一/

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);

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);
手心的温暖 2024-10-18 04:17:40

经过进一步研究,这似乎在 2.0 版本中不起作用。我现在可以升级到 3.0 版本,我相信现在这是可能的。

After further research it appears that this won't work in version 2.0. I am now in a position to upgrade to version 3.0 where i believe this is now possible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文