使用集合表映射多对一

时间:2014-05-07 12:09:06

标签: nhibernate nhibernate-mapping mapping-by-code

我有一个包含两个实体MachineProduct的简单案例,其中Machine可以有零个或一个Product。代码中不需要反向关联(可能是某种类型的集合)。

问题出在遗留的数据库模型中,我无法改变Machine表的结构,因此我创建了一个额外的表MachineProduct,其中包含两个表的外键。基本上你会为多对多关系做些什么,但在实践中,这个表中的MachineId将是独一无二的。

现在我需要在NHibernate中映射它。我能做的是将它映射为多对多集合,并确保Machine.Products集合中只有一个元素,但我觉得应该有更准确的方法来处理这个问题。我想这就是ORM映射的全部内容。

我使用NHibernate按代码映射,但XML映射示例也可以。

2 个答案:

答案 0 :(得分:0)

这是我受过教育的猜测。

正如您所建议的,在正常的M:N情况下,MachineProduct将是一个“链接表”并且可以重复。

我认为你可以“单一化”关系...使用“.Unique()”。

我认为这是在正确的树上咆哮。

public class MachineProductMap : ClassMap<MachineProductNHEntity>
{
    public MachineProductMap()
    {
        Schema("dbo");
        Table("MachineProduct");

        /* Your surrogate key setup here */
        Id(x => x.MachineProductUUID).GeneratedBy.GuidComb().Index("IX_MachineProduct_MachineProductUUID");

        References<MachineNHEntity>(x => x.ParentMachine)
            .Class(typeof(MachineNHEntity))
            .Not.Nullable()
             .Unique()
            .Column("ParentMachineUUID")
            .Index("IX_MachineProduct_ParentMachineUUID")
            .Cascade.SaveUpdate()
            ;
        ;


       References<ProductNHEntity>(x => x.ParentProduct)
            .Class(typeof(ProductNHEntity))
             .Nullable()
             .Unique()
            .Column("ParentProductUUID")
            .Index("IX_MachineProduct_ParentProductUUID")
            .Cascade.SaveUpdate()
            ;
        ;
    }
}

APPEND:

我认为上述情况有效,但你后来声明你不想要一个中间人实体。

所以这是使用“加入”的另一种尝试.....

我想你想要这样的东西:

public class Product
{
    public virtual int ProductSurrogateKey { get; set; } /* ID */
}   

public partial class Machine
    {
        public virtual Guid? MachineUUID { get; set; }
        public virtual Product TheProduct { get; set; }
    }

public class MachineMap : ClassMap<Machine>
{
    public MachineMap()
    {

        Table("Machine");

        Id(x => x.MachineUUID).GeneratedBy.GuidComb().Index("IX_Machine_MachineUUID");

        Join("MachineProductArtificialReferenceMaker", join =>
        {
            join.KeyColumn("ParentMachineUUID");
            join.References(prop => prop.TheProduct);
        });

    }
}

这会创建一个名为“ MachineProductArtificialReferenceMaker ”的表格。

此表有一个FK到Machine.MachineUUID。 (不是空的)

和FK到Product.ProductSurrogateKey(可空)

答案 1 :(得分:0)

我认为常规的最简单方法很多人应该做的工作,确保不要引用产品中的多对多关系。

<class name="Machine">
  <id ....>
  <bag name="Competencies" table="MachineProduct">
    <key column="machine_id"/>
   <many-to-many class="Product" column="product_id"/>
  </bag>
</class>

或定期一对多致力于。

<set name="MachineProduct" table="MachineProduct" cascade="all-delete-orphan" inverse="true">
  <key column="machine_id"/>
  <one-to-many class="MachineProduct"/>
</set>