1

я следующий класс и связанных отображений (Fluent NHibernate):NHibernate не загружая дочерние объекты

public class Category 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual string Description { get; set; } 
    public virtual Category ParentCategory { get; set; } 
    public virtual IList<Category> ChildCategories { get; set; } 
} 

Отображения:

public class CategoryMap : ClassMap<Category> 
{ 
    public CategoryMap() 
    { 
     Table("Categories"); 

     Id(x => x.Id).Column("Id").CustomType("Int32").Access.Property() 
     .CustomSqlType("int").Not.Nullable().Precision(10) 
     .GeneratedBy.Identity(); 

     Map(x => x.Description).Column("Description").Nullable() 
     .Generated.Never().CustomType(typeof (string)).Access 
     .Property().Length(250); 

     Map(x => x.Name).Not.Nullable().Generated.Never().CustomType("string") 
     .Access.Property().Column("Name").Length(50); 

     References(x => x.ParentCategory).Column("ParentCategoryId"); 
     HasMany(x => x.ChildCategories).KeyColumn("ParentCategoryId").Inverse() 
     .AsBag().Fetch.Select(); 
    } 
} 

Я создания двух Category объекта следующим образом:

var c = new Category 
     { 
      Name = "Ebooks", 
      Description = "Contains awz, mobi, pdf, epub and other 
       electronic books" 
     }; 
var cc = new Category 
     { 
      Name = "Kindle Books", 
      Description = "Contains Kindle ebook reader format books 
        (awz, mobi)", 
      ParentCategory = c 
     }; 
session.SaveOrUpdate(c); 
session.SaveOrUpdate(cc); 

Когда я пытаюсь получить доступ к сохраненным объектам:

var c = session.Load<Category>(1); 
var cc = c.ChildCategories; 

c содержит Category объект с Id 1, но его свойство ChildCategories является null.

Что я делаю неправильно?

PS: - Это мой первый эксперимент с NHibernate и так с Fluent NHibernate.

EDIT: - Работа выполнена. Мне нужно было закрыть сеанс, прежде чем открывать его для чтения. В противном случае он читается как раз из памяти, так как @Holf указал, что мне нужно было добавить Child Category в Category:

c.ChilCategories.Add (cc);

Я просто сделал следующим образом:

+0

'Fetch.Select()' просто выстрел в темноте, он не работает :( – TheVillageIdiot

+0

Что произойдет, если вы измените 'Session.load (1)' в 'session.Get (1)'? – Rippo

+0

@TheVillageIdiot благодарит за это. Я удивлен, что раньше не сталкивался с этой проблемой (хотя, возможно, ее взломали в прошлом), но повторное открытие сессии полностью решает ее –

ответ

0

Хотя вы перевалено одну сторону отношений, назначая «C» как ParentCategory из «CC», я не могу увидеть где-нибудь, что вы» ве сделал обратный. Я думаю, вам также нужно будет сделать

c.ChildCategories.Add (cc);

перед выполнением SaveOrUpdate.

+0

Я не думаю, что это важно или даже если Мне нужно сделать это, поскольку как «ChildCategories», так и «ParentCategory» сопоставляются с использованием одного и того же столбца «ParentCategoryId» на Карте. – TheVillageIdiot

+0

Это определенно важно. Карта - это все о том, как nHibernate указывать, как сопоставить граф объектов с соответствующей схемой базы данных Даже при этом сопоставлении nHibernate будет по-прежнему сохраняться только то, что ему дано. Если вы не добавили дочерний элемент в паттерн t перед сохранением, nHibernate не сделает этого от вашего имени. – Holf

0

Вы можете обновить карту следующим образом:

public class CategoryMap : ClassMap<Category> 
{ 
    public CategoryMap() 
    { 
     Table("Categories"); 

     Id(x => x.Id).Column("Id").CustomType("Int32").Access.Property() 
     .CustomSqlType("int").Not.Nullable().Precision(10) 
     .GeneratedBy.Identity(); 

     Map(x => x.Description).Column("Description").Nullable() 
     .Generated.Never().CustomType(typeof (string)).Access 
     .Property().Length(250); 

     Map(x => x.Name).Not.Nullable().Generated.Never().CustomType("string") 
     .Access.Property().Column("Name").Length(50); 

     References(x => x.ParentCategory).Column("ParentCategoryId"); 
     HasMany(x => x.ChildCategories).KeyColumn("ParentCategoryId").Inverse() 
     .Cascade.All(); 
    } 
} 

Кроме того, вы не можете быть уверены, что Id со значением 1 относится к родительской категории, используйте поставщику Linq для загрузки правильного объекта.

+0

Я попробую изменить мою карту. Но я уверен в 'Id = 1', поскольку в таблице всего две записи. У одного с 'Id = 2' есть' ParentCategoryId = 1' – TheVillageIdiot

Смежные вопросы