Question

I have poco class

public class Category : Entity<int>
{
    public virtual Category Parent;
    public virtual Iesi.Collections.Generic.ISet<Article> Articles {get; set;}
    public virtual Iesi.Collections.Generic.ISet<Category> ChildCategories {get; set;}
}

I'm not sure is this correct mapping for ChildCategories property

public class CategoryMap : ClassMapping<Category>
{
    public CategoryMap()
    {
       ...
       Set(x => x.ChildCategories,
          c => { c.Cascade(Cascade.DeleteOrphans); },
          r => { r.OneToMany(); }              
       );
    }
}

Any child category can have only one parent. Once more is this correct mapping? If you need more information please ask.

Update: Exception inner message is following

{"Could not determine type for: xxxx, 
for columns: NHibernate.Mapping.Column(Parent)"}

Update 2:

public class CategoryMap : ClassMapping<Category>
    {
        public CategoryMap()
        {
            Id(x => x.Id, m => m.Generator(Generators.GuidComb));

            Property(x => x.Name, m =>
            {
                m.Length(255);
                m.NotNullable(true);
            });

            Property(x => x.Parent, m =>
            {
                //m.NotNullable(true);
            });

            Set(x => x.ChildCategories,
              c => 
              { 
                c.BatchSize(25);
                c.Inverse(true);
                c.Cascade(Cascade.DeleteOrphans); 
                c.Key(k =>
                {
                    k.Column("ParentId");
                });
              },
              r => { r.OneToMany(); }              
           );


            Set(x => x.Articles,
              c => { c.Cascade(Cascade.DeleteOrphans); },
              r => { r.OneToMany(); }
            );            
        }
    }

Update 3

Property(x => x.Parent, m =>
            {
                m.Column("ParentId");
                m.NotNullable(true);
            });

Error

{"Could not determine type for: xxxx, 
for columns: NHibernate.Mapping.Column(ParentId)"}
Was it helpful?

Solution

Not so sure what the real issues is, but my standard xml mapping for parent-child collection would look like this:

<set name="ChildCategories" lazy="true"  batch-size="25" inverse="true">
  <key column="ParentId" />
  <one-to-many class="Category"/>
</set>

While lazy is (as far as I remember) default, I prefer explicit statements

I would say, that really essential is the information where to search for a Parnet column. This I would mapp for sure explicitly. And also the inverse and batch-size. So, following

This could be the mapping of the set

 ...
 Set(x => x.ChildCategories,
      c => 
      { 
        c.BatchSize(25);
        c.Inverse(true);
        c.Cascade(Cascade.DeleteOrphans); 
        c.Key(k =>
        {
            k.Column("ParentId");
        };
      },
      r => { r.OneToMany(); }              
   );

Few more information about why to use batch-sizing: How to Eager Load Associations without duplication in NHibernate?

Because we used (in my snippet) the Inverse ... the Parent must be mapped as well (and assigned)

UPDATE: The essential part of this mapping is the Parent mapping!

But Parent is not a value type property. It is a reference. That's why we have to map it like this:

ManyToOne(x => x.Parent, m =>
{

See: Mapping-by-Code - ManyToOne

we cannot use

// NOT correct mapping
Property(x => x.Parent
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top