我有一个包含两个实体Machine
和Product
的简单案例,其中Machine
可以有零个或一个Product
。代码中不需要反向关联(可能是某种类型的集合)。
问题出在遗留的数据库模型中,我无法改变Machine表的结构,因此我创建了一个额外的表MachineProduct,其中包含两个表的外键。基本上你会为多对多关系做些什么,但在实践中,这个表中的MachineId将是独一无二的。
现在我需要在NHibernate中映射它。我能做的是将它映射为多对多集合,并确保Machine.Products集合中只有一个元素,但我觉得应该有更准确的方法来处理这个问题。我想这就是ORM映射的全部内容。
我使用NHibernate按代码映射,但XML映射示例也可以。
答案 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>