NHibernate - 无法获得OneToMany关系的双方

时间:2014-04-02 18:42:18

标签: c# .net asp.net-mvc-4 nhibernate

上下文

我们有用户和邀请。用户可以拥有多个关联的邀请,邀请与一个用户关联。

我通过usersk表上的invite列对应psk表上的user主键列来表示这一点。

还有一个匹配的概念,但只有Invite的主键是其User外键和Match外键的组合时才与此问题相关。

我想最终:

  1. 用户拥有一个属性,该属性是他们参与的邀请的集合
  2. 邀请具有与其关联的用户
  3. 的属性

    在最高级别,我的方法是创建一组通过OneToMany关系绑定到用户的邀请,然后从邀请到用户创建一个ManyToOne映射。

    错误

    这是我的ManyToOne设置:

    ManyToOne(x => x.User, map => { 
        map.PropertyRef("PSK");  
    });
    

    引发此错误:

    {"ERROR: 42703: column invit0_.user does not exist"}
    

    这是正确的,因为没有用户列。但是尝试指定要使用的列会给我一个不同的错误:

    ManyToOne(x => x.User, map => { 
        map.PropertyRef("PSK"); 
        map.Column("usersk"); 
    });
    

    抛出错误:

    {"Error performing LoadByUniqueKey[SQL: SQL not available]"}
    

    由于内部异常:

    {"The given key was not present in the dictionary."}
    

    工具

    MVC4 WebApi,NHibernate Conformist ByCode mapping

    代码

    如果我只是尝试完成第一个目标,为用户创建一个属性邀请集,那么事情就会顺利进行。该代码如下:

    User.cs

    public class User {
        public User() { }
        public virtual int PSK { get; set; }
    
        public virtual ICollection<Invite> Invites { get; set; }
    }
    

    UserMap.cs

    public class UserMap : ClassMapping<User>
    {
        public UserMap()
        {
            Lazy(true);
    
            Schema("public");
            Table("user");
            Id(x => x.PSK, map =>
            {
                map.Column("psk");
                map.Generator(Generators.Sequence, g => g.Params(new {sequence = "user_psk_seq"}));
            });
    
            Set(x => x.Invites, 
                mapping =>
                {
                    mapping.Key(k =>
                    {
                        k.Column("usersk");
                    });
                    mapping.Inverse(true);
                },
                r => r.OneToMany());
        }
    }
    

    Invite.cs

    public class Invite {
        public virtual int MatchSK { get; set; }
        public virtual int UserSK { get; set; }
        public virtual User User { get; set; }
    
        #region NHibernate Composite Key Requirements
        public override bool Equals(object obj) {
            if (obj == null) return false;
            var t = obj as Invite;
            if (t == null) return false;
            if (MatchSK == t.MatchSK
             && UserSK == t.UserSK)
                return true;
    
            return false;
        }
        public override int GetHashCode() {
            int hash = GetType().GetHashCode();
            hash = (hash * CONSTANT) ^ MatchSK.GetHashCode();
            hash = (hash * CONSTANT) ^ UserSK.GetHashCode();
    
            return hash;
        }
        #endregion
    }
    

    InviteMap.cs

    public class InviteMap : ClassMapping<Invite> {
        public InviteMap() {
            Lazy(true);
    
            Schema("public");
            Table("invite");
            ComposedId(compId =>
                {
                    compId.Property(x => x.MatchSK, m => m.Column("matchsk"));
                    compId.Property(x => x.UserSK, m => m.Column("usersk"));
                });
    
            ManyToOne(x => x.User, map => { 
                map.PropertyRef("PSK");  
            });
        }
    }
    

    有了这个,如果我在InviteMap中注释掉ManyToOne代码,那么获取User会给我一个完全符合预期的填充Invites集合。

    结论

    帮助?我真的希望这是一个我错过的明显的概念问题。但是......在这方面随意让我失望。

    感谢您的时间。

1 个答案:

答案 0 :(得分:1)

正如我们通过讨论关于问题评论的整个主题所发现的那样,问题非常简单:它是关于在许多中使用.Column(...)代替.PropertyRef(...)的问题到一个映射。