【问题标题】:Map One-To-One Relationship Doesn't Allow Inserting映射一对一关系不允许插入
【发布时间】:2011-05-23 18:33:10
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

    我认为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 中是否有所不同。

    【讨论】:

    • 干杯,但如果您未指定一对一关系的约束,则不支持延迟加载。
    • 经过进一步调查。看来这解决了问题,但延迟加载仍然无法正常工作。一旦我抓住用户,它也会抓住细节。
    • 再次感谢,我尝试使用多对一映射映射用户端(我已使用新映射更新了我的原始问题)。但它仍然无法正常工作。我非常感谢您的帮助。谢谢
    • 尝试将映射更改为:References(x => x.Details);
    • 这行不通,因为用户表中没有 DetailsID 字段。
    【解决方案2】:

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

    Id(x=>x.UserId);
    

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

    【讨论】:

    • 干杯,但 UsersDetails 表中的 UserID 字段是对包含自动递增 id 的 Users 表的引用。因为是一对一的映射,所以UsersDetails表中的用户id也是主键。希望对您有所帮助。
    【解决方案3】:

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

    【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-12-05
        • 2014-02-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-17
        相关资源
        最近更新 更多