2010-03-06 225 views
0

我想弄清楚我认为只是一个简单的一对多使用流利Nhibernate映射。我希望有人可以指向我的正确的目录,实现这一对多关系 我有一个文章表和一个类别表 许多文章只能属于一个类别 现在我的Categores表有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个大类由于LEFT OUTER JOIN通过NHibernate的 任何想法,我在做什么错在这里使用? 感谢 [解决方法] 了几个小时,我在这里读NHibernate的文档后就是我想出了

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

使用NHibernate LINQ提供

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

回答

0

我真的不知道是什么问题,因为我不知道如何保存类别,但它可能是由映射中使用错误的级联设置引起的?

+0

我有保存任何实体 的问题是选择分类 没有问题我有一个的categoryId一个四篇文章关闭1“Finanace” 当我执行的测试情况下,我得到类别“财经”返回了多个倍。我试图得到的是四个类别,并可以访问引用它们的文章。 – Sammy 2010-03-07 00:21:44

+0

找到解决方案,请参阅问题的编辑2样本实施 – Sammy 2010-03-07 01:06:30

+0

请参阅对我的答案的编辑。希望这可以帮助。 – 2010-03-08 12:47:22

0

在HasMany上使用Join是不常见的;它通常用于引用,即一对多关系的许多方面。您应该延迟加载集合或使用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。文章,没有会话或会话已关闭 我最初的想法是查询数据库以获取类别和每个文章在每个类别中的计数。 您可否详细说明“在HasMany上使用加入是不寻常的;”我使用了映射类型,认为它是我见过的示例中的规范。 – Sammy 2010-03-08 02:35:37