流畅的nhibernate一对多映射

时间:2010-03-06 22:41:29

标签: nhibernate fluent-nhibernate

我试图弄清楚我认为只是使用流利的Nhibernate进行简单的一对多映射。我希望有人能指出我正确的目录来实现这一对多的关系 我有一个文章表和一个类别表 许多文章只能属于一个类别 现在我的分类表有4个类别,文章有一篇文章与cateory1

相关联

这是我的设置。

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>();

            }
        }
    }

由于Nhibernate使用左外连接,我得到了7个类别 知道我在这里做错了什么吗? 谢谢 [解] 几个小时后阅读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();

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

在HasMany上使用Join很不寻常;它通常用于引用,一对多关系的许多方面。您应该延迟加载集合或使用Fetch.Select,而不是您提出的解决方案。两者都会导致NH发出两个选择,一个用于加载类别,另一个用于加载其关联的文章。

附录:

您获得的错误非常简单:无法加载集合,因为用于加载父级的ISession超出了范围(或者其连接已关闭)。将获取模式设置为Select将解决此问题(我想,我还没有尝试过)。所以你的集合映射将是:

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

如果您可以保持ISession打开,我会建议延迟加载:

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

由于您遇到的问题,在集合映射上使用Join是不常见的。从一方发出连接将返回集合中每个对象的父对象,就像在SQL中一样。