【问题标题】:fluent nhibernate one to many mapping流利的休眠一对多映射
【发布时间】:2010-03-06 22:41:28
【问题描述】:

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

这是我的设置。

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

【问题讨论】:

    标签: nhibernate fluent-nhibernate


    【解决方案1】:

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

    【讨论】:

    • 我在保存任何实体时都没有问题问题是选择类别当我执行测试用例时,我有四篇文章的 categoryId 关闭 1“金融”我得到了“金融”类别多次返回。我想要得到的是四个类别,并且可以访问引用它们的文章。
    • 找到解决方案,请参阅问题编辑以了解 2 个示例实现
    【解决方案2】:

    在 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 中一样。

    【讨论】:

    • 詹姆斯,如果我不使用文章列表,您推荐的将是一个很好的解决方案。当我尝试使用它来检查计数时,在使用 Fetch.Select 或 LoazyLoad 时出现此异常。 Initializing[IMB.Domain.Entities.Category#4]-failed to lazily initialize a collection of role: IMB.Domain.Entities.Category.Articles, no session or session was closed 我最初的想法是查询数据库以获取类别和每篇文章在每个类别中的计数。您能否详细说明“在 HasMany 上使用 Join 是不寻常的;”,我使用了映射类型,认为这是我所看到的示例中的规范。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-07
    • 1970-01-01
    • 2019-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多