nHibernate - 有没有办法调试TPH对象的创建?

时间:2015-01-23 16:46:24

标签: nhibernate table-per-hierarchy

我有一个按代码映射的每层结构表结构,以及一个包含数据的表--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);
            }
        }

1 个答案:

答案 0 :(得分:0)

原因(我猜)是因为第一行中的一行通过其父属性引用代理对象,并且由于它具有基本类型而且没有急切地获取,因此NHibernate只能创建此基本类型的代理来表示它。稍后它会找到与行相同的对象,并将现有的引用移交给它(代理)。

一个简单的解决方法是禁用父属性的LazyLoading:

ManyToOne(x => x.Parent, p => {
            p.Column("Parent_Id");
            p.Class(typeof(BaseTreeNode));
            p.Lazyload(false);
            p.NotNullable(false);
        });