Fluent nHibernate - 使用复合键映射子项,产生空引用
给定一个简单的父级 ->子(CK,CK)设置如下..我在添加新的子对象并获取父引用时遇到问题。所以我会以这种方式添加对象..
var parent = new Parent{
Children = new List<Child>{
new Child{
Other = otherReference
}
}
};
或者甚至使用 Add()
方法添加它...
parent.Children.Add(new Child { Other = other });
对 Parent
的引用不会被推送。它最终只是作为一个 null 属性。我得到以下异常。
{“无法将 NULL 值插入到表“mssql_test.Children”的列“ParentId”中;列不允许为空值。INSERT 失败。\r\n该语句已终止。”}
我可以这……
new Child {
Parent = parentReference,
Other = otherReference
}
但这似乎有点多余。我的理解是它应该能够自行推断引用。如果这是不可能的,也许我只是误会。谁能帮助我吗?我的代码概述如下。
类
class Parent {
int Id { get; set; }
IList<Child> Children { get; set; }
}
class Other {
int Id { get; set; }
}
class Child {
Parent Parent { get; set; }
Other Other { get; set; }
// other properties
}
映射
ChildMap() {
CompositeId()
.KeyReference(x => x.Parent, "ParentId")
.KeyReference(x => x.Other, "OtherId");
}
ParentMap(){
HasManyToMany(x => x.Children)
.AsBag()
.ChildKeyColumns.Add(new[] { "ParentId", "OtherId" })
.Inverse()
.Cascade.All())
.Table("[Test]");
}
Given a simple parent -> child (CK,CK) setup like this .. I am having trouble with adding a new child object and it getting the parent reference. So I would add the object in such a way ..
var parent = new Parent{
Children = new List<Child>{
new Child{
Other = otherReference
}
}
};
Or even adding it using the Add()
method...
parent.Children.Add(new Child { Other = other });
The reference to the Parent
does not get pushed through. It just ends up as a null property. I get the following exception.
{"Cannot insert the value NULL into column 'ParentId', table 'mssql_test.Children'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated."}
I can do this ...
new Child {
Parent = parentReference,
Other = otherReference
}
But that seems a bit redundant. My understanding is that it should be able to infer the reference by itself. If this is not possible, perhaps I am just misunderstanding. Can anyone help me? I have an outline of my code below.
Classes
class Parent {
int Id { get; set; }
IList<Child> Children { get; set; }
}
class Other {
int Id { get; set; }
}
class Child {
Parent Parent { get; set; }
Other Other { get; set; }
// other properties
}
Mapping
ChildMap() {
CompositeId()
.KeyReference(x => x.Parent, "ParentId")
.KeyReference(x => x.Other, "OtherId");
}
ParentMap(){
HasManyToMany(x => x.Children)
.AsBag()
.ChildKeyColumns.Add(new[] { "ParentId", "OtherId" })
.Inverse()
.Cascade.All())
.Table("[Test]");
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如 @KeithS 指出的,问题在于您将 Child 集合映射为 HasManyToMany,而它应该是 HasMany。映射应如下所示:
As @KeithS points out the problem is that you have mapped the Child collection as HasManyToMany when it should be HasMany. Here is how the mapping should look:
您没有将父级映射为子级的属性。 NHibernate(和 FluentNH)仅映射您告诉它们的内容;你的对象上可以有十几个字段,但如果你只映射其中一个字段,那么 NH 在为你提供一个实例时就会提供这些字段。您应该在映射中包含对父级的“引用”方法,将父级的关键字段指定为 FK 引用。这应该为您提供对象层次结构中的“反向引用”。
另外,看起来您应该只有一对多(使用 HasMany),而不是父端的多对多。父母可以有多个孩子,但一个孩子只有一个父母。 ManyToMany 可能有效,但它会在父项和子项之间创建冗余的交叉引用表。
You are not mapping the Parent as a property of the Child. NHibernate (and FluentNH) only map what you tell them to; you could have a dozen fields on your object, but if you only map one of them, that's all NH will provide when it hydrates an instance for you. You should include a "References" method to the Parent in your mapping, specifying the Parent's key field as the FK reference. That should give you the "backreference" you have in your object hierarchy.
Also, it looks like instead of a many-to-many on the Parent side, you should have just a one-to-many (using HasMany). Parents can have many Children, but a Child has one and only one Parent. ManyToMany may work, but it creates a redundant cross-reference table in between Parent and Child.