我有一个存储树结构的应用程序,并且能够很好地生成数据库,但是在插入时我得到了一个异常。我简化了代码以缩小问题范围。
要保存的课程:
public class Node
{
public virtual int NodeId { get; set; }
public virtual string Name { get; set; }
public virtual Node Parent { get; set; }
public virtual IList<Node> Children { get; set; }
}
这是映射器代码:
public sealed class NodeMap : ClassMap<Node>
{
public NodeMap()
{
Id(n => n.NodeId).GeneratedBy.Identity();
Map(n => n.Name);
References(n => n.Parent).LazyLoad().Nullable();
HasMany(n => n.Children).LazyLoad().KeyColumn("ParentId");
}
}
当我执行像dataClient.Insert(new Node { Name = "Test" });
这样的插入时,我得到一个例外说法:
NHibernate.Exceptions.GenericADOException:无法插入:[Model.Node] [SQL:INSERT INTO [Node](Name,NodeId)VALUES(?,?);选择SCOPE_IDENTITY()]
内部例外说:
System.Data.SqlClient.SqlException:当IDENTITY_INSERT设置为OFF时,无法在表'Node'中为identity列插入显式值。
这实际上是完全可以理解的,但我只是想知道为什么它试图为NodeId设置一个显式值。当我删除引用部分时,插入经过,所以必须以某种方式与之相关。
FluentNHibernate的版本是1.2.0.712,NHibernate的版本是3.1.0.4000。
答案 0 :(得分:2)
这是因为引用的默认列是typename + id
,恰好是与id列相同的名称。在参考文献中明确说明。
References(n => n.Parent, "ParentId").LazyLoad().Nullable();
更新:按惯例
public class ReferenceColumnConvention : IReferenceConvention
{
public void Apply(IManyToOneInstance instance)
{
// uncomment if needed
//if (instance.EntityType == instance.Property.PropertyType)
instance.Column(instance.Name + "id");
}
}