我有一个存储树结构的应用程序并且能够很好地生成数据库,但是在插入时出现异常。我简化了代码以缩小问题范围。
要保存的类:
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: could not insert: [Model.Node][SQL: INSERT INTO [Node] (Name, NodeId) VALUES (?, ?); select SCOPE_IDENTITY()]
内部异常说:
System.Data.SqlClient.SqlException: Cannot insert explicit value for identity column in table 'Node' when IDENTITY_INSERT is set to OFF.
这其实完全可以理解,但我只是想知道为什么它试图为 NodeId 设置一个显式值。当我删除引用部分时,插入会通过,因此它必须以某种方式与该部分相关。
FluentNHibernate的版本是1.2.0.712,NHibernate的版本是3.1.0.4000。
最佳答案
这是因为引用的默认列是 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");
}
}
关于nhibernate - FluentNHibernate与树结构的持久化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9551456/