我有一个按代码映射的每层结构表结构,以及一个包含数据的表--116行。最初,该表(以及整个数据库)是使用Entity Framework Code First方法创建的。由于某些原因,我从EF切换到NH,并尝试从提到的表中获取数据导致115个正确创建的对象,并且只有一个行导致具有错误基本类型的代理对象。 我试图找到其他类似行和错误行之间的差异(有30行具有相同的Discriminator值),但我失败了。 因此,问题是 - 我可以用什么调试技术来解决我的问题?
在一个小小片段下面我如何从表中加载数据:
var more = _dbSession.Query<BaseTreeNode>()
.Where(tn => !tn.IsTemplate)
.OrderBy(tn => tn.Id)
.ToList();
这是一个映射:
public class BaseTreeNodeMapping : ClassMapping<BaseTreeNode> {
public BaseTreeNodeMapping() {
Debug.WriteLine("{0}", GetType());
Table("BaseTreeNodes");
Id(x => x.Id);
Discriminator(x => {
x.Force(true);
x.Formula("arbitrary SQL expression");
x.Insert(true);
x.Length(128);
x.NotNullable(true);
x.Column("Discriminator");
});
Property(p => p.Name);
Property(x => x.SortOrder);
Property(x => x.IsTemplate);
Property(x => x.ArchiveUid);
Property(x => x.LastChangedAt, x => x.Lazy(false));
Property(x => x.LastChangedBy);
// Complex Properties
ManyToOne(x => x.Parent, p => {
p.Column("Parent_Id");
p.Class(typeof(BaseTreeNode));
p.NotNullable(false);
});
ManyToOne(x => x.ComplexNode, cn => {
cn.Column("ComplexNode_Id");
cn.NotNullable(true);
});
ManyToOne(x => x.ComplexStructure, cn => {
cn.Column("ComplexStructure_Id");
cn.NotNullable(true);
});
ManyToOne(x => x.ContentNode, cn => {
cn.Column("ContentNode_Id");
cn.NotNullable(true);
});
}
public class EntityMapping : SubclassMapping<Entity> {
public EntityMapping() {
DiscriminatorValue("Entity");
ManyToOne(p => p.TypeCode, t => {
t.Column("TypeCode_Id");
t.Class(typeof(TypeCode));
t.Fetch(FetchKind.Join);
t.NotNullable(true);
t.Lazy(LazyRelation.NoLazy);
});
Property(p => p.ArchivedFrom);
}
}
答案 0 :(得分:0)
原因(我猜)是因为第一行中的一行通过其父属性引用代理对象,并且由于它具有基本类型而且没有急切地获取,因此NHibernate只能创建此基本类型的代理来表示它。稍后它会找到与行相同的对象,并将现有的引用移交给它(代理)。
一个简单的解决方法是禁用父属性的LazyLoading:
ManyToOne(x => x.Parent, p => {
p.Column("Parent_Id");
p.Class(typeof(BaseTreeNode));
p.Lazyload(false);
p.NotNullable(false);
});