流畅的NHibernate多对多映射自我引用与关联表

时间:2016-11-19 15:45:07

标签: c# nhibernate fluent-nhibernate nhibernate-mapping fluent-nhibernate-mapping

仅供记录:我使用C#,Fluent NHibernate和MySQL 5.

我曾经在这个项目中使用NHibernate,但最近我决定使用Fluent NHibernate。而且我在绘制多对多关系时遇到了问题,这种关系引用了自我和附加列。

我有表项目。项目可以有许多组件,也来自表。这些组件也可以被其他项目使用。 例如,项目A需要两个组件,即项目B和项目C.项目B也用于项目D和项目E,依此类推。

我使用了关联表,我需要额外的列来表示他们的关系。因此,将会有2个一对多的关系。这是我的数据库结构。

  1. 物品
    • ID
    • 名称
  2. 先决条件[关联表]
    • ID
    • Item_ID [FK_Item1] //要制作的项目。
    • Component_ID [FK_Item2] //此项目的组件。
    • 重量//附加栏。
  3. 这是我的先决条件表的映射:

    public PrerequisiteMap()
    {
        Id(x => x.ID).GeneratedBy.Native();
    
        References(x => x.Item).Column("Item_ID");
        References(x => x.Component).Column("Component_ID");
    
        Map(x => x.Need);
    }
    

    这是我对Item表的映射:

    public ItemMap()
    {
        Id(x => x.ID).GeneratedBy.Native();
    
        HasMany(x => x.PrerequisitesParent).KeyColumn("Item_ID").Cascade.All();
        HasMany(x => x.PrerequisitesComponent).KeyColumn("Component_ID").Cascade.All ;
    
        Map(x => x.Name);
    }
    

    这是我的先决条件课程:

    public virtual UInt64 ID { get; set; }
    // item.
    public virtual UInt64 Item_ID { get; set; }
    public virtual Item Item { get; set; }
    // Component.
    public virtual UInt64 Component_ID { get; set; }
    public virtual Item Component { get; set; }
    
    // prerequisite properties.
    public virtual float Need { get; set; }
    

    这是我的项目类:

    // Item properties.
    public virtual UInt64 ID { get; protected set; }
    public virtual string Name { get; set; }
    public virtual IList<Prerequisite> PrerequisitesComponent { get; set; }
    public virtual IList<Prerequisite> PrerequisitesParent { get; set; }
    

    我遇到的问题是,每当我尝试使用先决条件保存/更新Item时,Component_ID和Item_ID始终具有相同的值。我在先决条件表中创建了新的项目X,其中包含项目Y和项目Z,我得到了这些:

    ID |的Item_ID | COMPONENT_ID |需要

    1 | X | X | 10

    2 | X | X | 20

    而不是预期的结果

    1 | X | Y | 10

    2 | X | Z | 20

    保存时这是我的代码:

        using (var session = SessionFactoryProvider.OpenSession())
        {
            using (var trans = session.BeginTransaction())
            {
                var item = session.Get<Item>((UInt64)1); // Item to be updated.
                var item2 = session.Get<Item>((UInt64)2); // Component 1
                var item3 = session.Get<Item>((UInt64)3); // Component 2
    
                item.PrerequisitesComponent.Add(new Prerequisite() { Item = item, Component = item2, Need = 100f}); // adding new prerequisite from component 1 (item2)
                item.PrerequisitesComponent.Add(new Prerequisite() { Item = item, Component = item3, Need = 100f }); // adding new prerequisite from component 2 (item3)
    
                session.SaveOrUpdate(item);
                try
                {
                    trans.Commit();
                }
                catch(GenericADOException ex)
                {
                    MessageBox.Show(ex.InnerException.ToString());
                }
    
            }
    
        }
    

    这可能是什么问题?是因为我引用了同一张桌子吗?或者我错误地映射了它?

    我读了其他类似的问题many to many from product to productmany to many self referencing,但似乎他们没有在关联表中使用其他列?

    非常感谢任何帮助,谢谢。

1 个答案:

答案 0 :(得分:1)

愚蠢的我..我使用错误的参考物品。

我将item.PrerequisiteComponent更改为item.PrerequisiteParent,一切正常。