2010-03-06 4 views
0

Я пытаюсь понять, что я думал, было просто от простого к сопоставлению с использованием свободного Nhibernate. Я надеюсь, что кто-то может указать мне на правильный каталог, чтобы достичь этого во многих отношениях. У меня есть таблица статей и таблица категорий. . Многие статьи могут принадлежать только одной категории. Теперь таблица «Мои категории» содержит 4 категории и статьи. с cateory1Свободно nhibernate от одного до многих картирование

вот моя установка.

using FluentNHibernate.Mapping; 
using System.Collections; 
using System.Collections.Generic; 

namespace FluentMapping 
{ 
    public class Article 
    { 

     public virtual int Id { get; private set; } 
     public virtual string Title { get; set; } 
     public virtual Category Category{get;set;} 
    } 
    public class Category 
    { 
     public virtual int Id { get; private set; } 
     public virtual string Description { get; set; } 
     public virtual IList<Article> Articles { get; set; } 
     public Category() 
     { 
      Articles=new List<Article>(); 
     } 

     public virtual void AddArticle(Article article) 
     { 
      article.Category = this; 
      Articles.Add(article); 
     } 
     public virtual void RemoveArticle(Article article) 
     { 
      Articles.Remove(article); 
     } 

    } 
    public class ArticleMap:ClassMap<Article> 
    { 
     public ArticleMap() 
     { 
      Table("Articles"); 
      Id(x => x.Id).GeneratedBy.Identity(); 
      Map(x => x.Title); 
      References(x => x.Category).Column("CategoryId").LazyLoad(); 

     } 
     public class CategoryMap:ClassMap<Category> 
     { 
      public CategoryMap() 
      { 
       Table("Categories"); 
       Id(x => x.Id).GeneratedBy.Identity(); 
       Map(x => x.Description); 
       HasMany(x => x.Articles).KeyColumn("CategoryId").Fetch.Join(); 
      } 
     } 
    } 
} 

если я запускаю этот тест

[Fact] 
    public void Can_Get_Categories() 
    { 
     using (var session = SessionManager.Instance.Current) 
     { 
      using (var transaction = session.BeginTransaction()) 
      { 
       var categories = session.CreateCriteria(typeof(Category)) 
           //.CreateCriteria("Articles").Add(NHibernate.Criterion.Restrictions.EqProperty("Category", "Id"))         
       .AddOrder(Order.Asc("Description")) 
           .List<Category>(); 

      } 
     } 
    } 

Я получаю 7 Категорию из-за левые внешнее соединение, используемого NHibernate любой идея, что я делаю неправильно здесь? Благодаря [Solution] После нескольких часов чтения NHibernate документы я вот что я придумал

var criteria = session.CreateCriteria(typeof (Category)); 
        criteria.AddOrder(Order.Asc("Description")); 
        criteria.SetResultTransformer(new DistinctRootEntityResultTransformer()); 
var cats1 = criteria.List<Category>(); 

Использование NHibernate поставщика

var linq = session.Linq<Category>(); 
        linq.QueryOptions.RegisterCustomAction(c => c.SetResultTransformer(new DistinctRootEntityResultTransformer())); 
        var cats2 = linq.ToList(); 

ответ

0

Linq Я не знаю, в чем проблема , потому что я не знаю, как вы сохраняете категории, но это может быть вызвано неправильной настройкой каскада в сопоставлении?

+0

У меня нет никаких проблем в сохранении какого-либо из субъектов Проблемы заключается в выборе категории У меня есть четыре статьи с CategoryId от 1 «Finanace» , когда я исполняю тест, я получаю Категорию «Финансы» вернулся множественным раз. я пытаюсь получить четыре категории и иметь доступ к статьям, ссылающимся на них. – Sammy

+0

Найдено решение, см. «Редактирование вопроса» для 2 примеров реализации – Sammy

+0

См. Изменения в моем ответе. Надеюсь это поможет. –

0

Использование Join на HasMany необычно; он обычно используется в ссылках, много сторон отношений «один ко многим». Вместо решения, которое вы придумали, вы должны ленить загрузить коллекцию или использовать Fetch.Select. Оба приведут к тому, что NH выпустит два варианта, один для загрузки категории, а другой - для загрузки связанных статей.

Добавление:

Ошибка вы получаете довольно прямолинейно: коллекция не может быть загружен, потому что ISession, который был использован для загрузки родителя выходит за рамки (или его соединение было закрыто) , Настройка режима выборки на «Выбор» решит это (я думаю, я не пробовал). Таким образом, ваше отображение коллекции будет:

HasMany(x => x.Articles).KeyColumn("CategoryId").Fetch.Select(); 

Если вы можете держать ISession открытым, я бы рекомендовал отложенную загрузку:

HasMany(x => x.Articles).KeyColumn("CategoryId").LazyLoad(); 

Необычно использовать Регистрацию на отображение коллекции из-за проблемы вы запускали в , Выдача соединения с одной стороны будет возвращать родительский объект для каждого объекта в коллекции, как это было бы в SQL.

+0

James, то, что вы рекомендовали, было бы хорошим решением, если бы список статей не использовался. когда я пытаюсь использовать его для проверки счета, я получаю это исключение при использовании Fetch.Select или LoazyLoad. Инициализация [IMB.Domain.Entities.Category # 4] - не удалось лениво инициализировать коллекцию роли: IMB.Domain.Entities.Category.Статьи, сеанс или сеанс не закрыты Моя первоначальная идея заключалась в запросе базы данных, чтобы получить категории и количество каждой статьи в каждой категории. Можете ли вы подробно остановиться на «Использование Join on HasMany необычно», я использовал тип отображения, считая, что это норма из примеров, которые я видел. – Sammy

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