我确信有人必须在此之前完成此操作 - 查看以前的查询,它可能无法用Fluent完成 - 但是这里有:
我有以下映射
正如您可能发现的那样 - 这不会起作用,因为子表上的键与父表不匹配,因此错误将是外键合约上的字段数不匹配 . 但是,我无法更改基础表(并且关系是有效的) . 有没有办法解决这个流畅的nhibernate所以我可以以某种方式忽略复合字段上的预期连接,只加入匹配的那个(即field_one?)Hibernate期望在两个映射中都存在字段1和字段2 .
public ParentMap()
{
Table("dbo.SOMEPARENT");
OptimisticLock.None();
LazyLoad();
CompositeId()
.KeyReference(x => x.FieldOne, x => x.Access.CamelCaseField(Prefix.Underscore), "field_one")
.KeyReference(x => x.FieldTwo, x => x.Access.CamelCaseField(Prefix.Underscore), "field_two");
HasMany(x => x.ChildData)
.Access.CamelCaseField(Prefix.Underscore)
.Cascade.AllDeleteOrphan()
.KeyColumns.Add("field_one")
.NotFound.Ignore();
}
public ChildDataMap()
{
Table("dbo.SOMECHILD");
OptimisticLock.None();
LazyLoad();
CompositeId()
.KeyProperty(x => x.FieldOne, x => x.Access.CamelCaseField(Prefix.Underscore).ColumnName("field_one"))
.KeyProperty(x => x.FieldTwo, x => x.Access.CamelCaseField(Prefix.Underscore).ColumnName("field_two"))
.KeyProperty(x => x.FieldThree, x => x.Access.CamelCaseField(Prefix.Underscore).ColumnName("field_three"))
.KeyProperty(x => x.FieldFour, x => x.Access.CamelCaseField(Prefix.Underscore).ColumnName("field_four"));
Map(x=>x.DontExecTrigger).Column("dont_exec_trigger").Access.CamelCaseField(Prefix.Underscore);
Map(x=>x.DateField).Column("date_field").Access.CamelCaseField(Prefix.Underscore);
Map(x=>x.DataField).Column("data_field").Access.CamelCaseField(Prefix.Underscore);
References(x => x.Parent)
.Access.CamelCaseField(Prefix.Underscore)
.Cascade.All()
.Fetch.Select()
.Columns("field_one")
.NotFound.Ignore()
.Not.LazyLoad();
}
1 回答
从纯数据库的角度来看,如果ChildDataMap FieldOne值始终出现在ParentMap FieldOne中,并且FieldOne在ParentMap中是唯一的,那么从前者到后者有一个外键 . 但它也意味着FieldOne是(独特的)ParentMap的候选键 .
您应该声明FK和UNIQUE数据库约束 . 你说你不能改变表,但如果约束有效,那么它不会影响它的任何用途 . 这应该允许您声明ChildDataMap FirstOne引用ParentMap FirstOne . 两列集仍然可以声明为PK(假设它是) . 但是如果ParentMap FieldTwo也是唯一的,它也应该被声明为UNIQUE,因此可以作为单列FK目标使用 .
可能已经声明了UNIQUE约束和/或FK . 也许您应该在ParentMap中为FirstOne声明相应的唯一属性 . KeyColumns.Add应该依赖于它,并允许您在ChildDataMap中声明引用 . 但我想这就是你的代码无效的地方 .
如果Hibernate没有自动加入同名字段,那么你就不能声明引用并在一个字段上进行自己的连接以获得一组引用,其中当然只有一个元素 .
目前尚不清楚你的意思是“你不能改变表格”(这包括,你不能添加有效的约束?)或“关系是有效的”(这是否意味着,Parent中的FieldOne是唯一的?) . 如果您发布了所有相关代码,也会有所帮助:即包括约束在内的表格延迟 .
如果可以定义新表,则可以使用添加的约束添加StricterParentMap,并将ParentMap声明为其视图 . 这不会影响他人对它的使用,也可能不算“不能改变” .