在fluentnhibernate中使用引用作为id

时间:2010-09-03 10:07:12

标签: fluent-nhibernate nhibernate-mapping

我有一个包含父级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");

我希望子类不具有不同的Id字段,而只是对父项的引用,因为永远不会有没有父项的子项。但是,在数据库中,我只想存储父级的id。

我有什么想法可以做到这一点?

3 个答案:

答案 0 :(得分:5)

以下作品:

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

参考的ReadOnly对于不能获得异常非常重要

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

我的子类仍然调用了Id属性。似乎Parent.Id的Id引用混淆了nhibernate,它试图调用child.Id。 我把以下内容添加到了孩子身上,现在它似乎工作了..虽然这是一个非常丑陋的黑客。

public virtual int Id {
    get { return Parent.Id; }
    set { Debug.Assert(value == Parent.Id); }
}

答案 1 :(得分:0)

多年来,FluentNHibernate的API发生了变化,因此我不确定在最初询问此问题时是否可以使用此语法,但如果将其作为复合ID映射,则现在可以将引用用作id。我不会称之为黑客,但有点奇怪,你必须将引用映射到父实体作为复合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
}

答案 2 :(得分:0)

也许even this one帖子可以提供帮助。
我已经使用了注释.Cascade.SaveUpdate()。我的案例是父母的一个人在两边都注释了注释

Obs:语言PT-BR