代码之家  ›  专栏  ›  技术社区  ›  simendsjo

在fluentnhibernate中使用引用作为id

  •  7
  • simendsjo  · 技术社区  · 14 年前

    我有一个子表,其中包含父表的id。这是一对一映射,但子表可能缺少值。我有问题映射到这个没有得到一个错误,虽然。。。我试过几种方法:映射同一列,具有不同的属性等等。。

    Parent table
      int id
    
    Child table
      int parentid
    
    Parent class
      int id
    
    Child class
      Parent parent // note I'm referencing parent, not using an int id..
    

    映射

    Id(x => x.Parent)
      .Column("parentid"); // fails
    
    Id(x => x.Parent.Id)
      .Column("parentid"); // fails
    
    References(x => x.Parent)
      .Column("parentid"); // fails - missing id
    
    // Adding an id field in addition to parent for
    // child class (id is then the same as parent.id)
    // fails on save
    Id( x => x.Id ) 
      .Column("parentid");
    References(x => x.Parent)
      .Column("parentid");
    

    我希望child类没有一个不同的Id字段,而只是一个对parent的引用,因为没有父类就不可能有子类。但是,在数据库中,我只想存储父级的id。

    你知道我该怎么做吗?

    3 回复  |  直到 11 年前
        1
  •  5
  •   simendsjo    14 年前

    以下工作:

    Id(x => x.Parent.Id).Column("MemberID");
    References(x => x.Parent).Column("MemberID").ReadOnly();
    

    编辑:不是那么简单。。。

    我的子类仍然有被调用的Id属性。似乎是的Id参考父项Id混淆了nhibernate,它试图呼叫子项Id相反。 我在child中添加了以下内容,现在它似乎起作用了。。一个相当丑陋的黑客。

    public virtual int Id {
        get { return Parent.Id; }
        set { Debug.Assert(value == Parent.Id); }
    }
    
        2
  •  0
  •   Randy Burden    11 年前

    FluentNHibernate的API多年来一直在变化,所以我不确定这个语法在最初提出这个问题时是否可用,但是如果你将引用映射为复合id,你现在可以使用它作为id。我不会称之为hack,但有点奇怪的是,你必须将引用映射到父实体作为复合id的一部分。下面是一个完整的示例:

    public class ParentMap : ClassMap<Parent>
    {
        public ParentMap()
        {
            Table( "StackOverflowExamples.dbo.Parent" );
    
            Id( x => x.ParentId );
            Map( x => x.FirstName );
            Map( x => x.LastName );
        }
    }
    
    public class OnlyChildOfParentMap : ClassMap<OnlyChildOfParent>
    {
        public OnlyChildOfParentMap()
        {
            Table( "StackOverflowExamples.dbo.OnlyChildOfParent" );
    
            CompositeId().KeyReference( x => x.Parent, "ParentId" );
            Map( x => x.SomeStuff );
            Map( x => x.SomeOtherStuff );
        }
    }
    
    public class Parent
    {
        public virtual int ParentId { get; set; }
        public virtual string FirstName { get; set; }
        public virtual string LastName { get; set; }
    }
    
    public class OnlyChildOfParent
    {
        public virtual Parent Parent { get; set; }
        public virtual string SomeStuff { get; set; }
        public virtual string SomeOtherStuff { get; set; }
    
        #region Overrides
    
        public override bool Equals( object obj )
        {
            if ( obj == null || GetType() != obj.GetType() )
                return false;
    
            var child = obj as OnlyChildOfParent;
    
            if ( child != null && child.Parent != null )
            {
                return child.Parent.ParentId == Parent.ParentId;
            }
    
            return false;
        }
    
        public override int GetHashCode()
        {
            return Parent.ParentId;
        }
    
        #endregion Overrides
    }
    
        3
  •  0
  •   Community noseratio    7 年前

    this 波斯特能帮上忙。
    我用了注释 .Cascade.SaveUpdate() .
    我的案例是父母的一个儿子在两边都做了注解

    Obs:语言PT-BR