0

I have a table-per-hierarchy structure mapped by code, and a table with data - 116 rows. Initially this table (and a whole database) was created using Entity Framework Code First approach. Due to some reasons I am switching from EF to NH, and attempt to fetch data from mentioned table results in 115 correctly created objects and only one single row results in proxy object with wrong base type. I tried to find differences between other similar rows and faulty one (there are 30 rows with same Discriminator value), but I failed. Thus, question is - what debug technics can I use to solve my problem?

Below a small snippet how I load data from the table:

var more = _dbSession.Query<BaseTreeNode>()
                .Where(tn => !tn.IsTemplate)
                .OrderBy(tn => tn.Id)
                .ToList();

And this is a mapping:

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);
            }
        }
DarkDeny
  • 1,750
  • 2
  • 21
  • 31

1 Answers1

0

The reason (i guess) is because one of the first rows references the proxy object through its parent property and since this has the basetype and is not eagerly fetched NHibernate can only create a proxy of this basetype to represent it. Later on it finds the same object as row and hands out the existing reference to it (the proxy).

An easy fix is to disable LazyLoading for the Parent property:

ManyToOne(x => x.Parent, p => {
            p.Column("Parent_Id");
            p.Class(typeof(BaseTreeNode));
            p.Lazyload(false);
            p.NotNullable(false);
        });
Firo
  • 30,626
  • 4
  • 55
  • 94