nhibernate - NHibernate FetchMany 在两个以上的表上是否损坏?

标签 nhibernate entity-framework

鉴于此:

namespace TheEntities
{
    [DataContract(IsReference=true)]    
    public class Question
    {
        [DataMember] public virtual int QuestionId { get; set; }
        [DataMember] public virtual string Text { get; set; }
        [DataMember] public virtual string Poster { get; set; }

        [DataMember] public virtual IList<QuestionComment> Comments { get; set; }
        [DataMember] public virtual IList<Answer> Answers{ get; set; }



        [DataMember] public virtual byte[] RowVersion { get; set; }
    }

    [DataContract]
    public class QuestionComment
    {
        [DataMember] public virtual Question Question { get; set; }        

        [DataMember] public virtual int QuestionCommentId { get; set; }
        [DataMember] public virtual string Text { get; set; }
        [DataMember] public virtual string Poster { get; set; }
    }


    [DataContract(IsReference = true)]
    public class Answer
    {
        [DataMember] public virtual Question Question { get; set; }

        [DataMember] public virtual int AnswerId { get; set; }
        [DataMember] public virtual string Text { get; set; }
        [DataMember] public virtual string Poster { get; set; }

        [DataMember] public virtual IList<AnswerComment> Comments { get; set; }

    }

    [DataContract]
    public class AnswerComment
    {
        [DataMember] public virtual Answer Answer { get; set; }

        [DataMember] public virtual int AnswerCommentId { get; set; }
        [DataMember] public virtual string Text { get; set; }
        [DataMember] public virtual string Poster { get; set; }
    }

}

Entity Framework 不会为 Answer、QuestionComment、AnswerComment 生成重复的对象,而 NHibernate 会生成重复的对象。

public Question OpenQuestion(int id)
{
    var repo = QuestionRepository;

    var query = repo.All.Where(y => y.QuestionId == id);

    if (QuestionRepository.GetType() == typeof(EfRepository<Question>))
    {                
        query = query
                .Include("Answers")
                    .Include("Answers.Comments")
                .Include("Comments");

        return query.Single();
    }
    else if (QuestionRepository.GetType() == typeof(NhRepository<Question>))
    {                
        // kinda sad, produces duplicate objects
        query = query
                .FetchMany(x => x.Answers)
                    .ThenFetchMany(x => x.Comments)
                .FetchMany(x => x.Comments);
    }
    else
        throw new Exception("Something unsupported");

    return query.Single();
}

这也会产生重复的对象(三层深,使用三个关系):

query = query
    .FetchMany(x => x.Answers)
    .ThenFetchMany(x => x.Comments)

这也会产生重复的对象(仅两层深,但使用三个关系):

query = query
    .FetchMany(x => x.Answers)
    .FetchMany(x => x.Comments);

这不会产生重复的对象,但是急切加载仅适用于两个深度级别和两个关系,即从问题到答案。对于提问评论和回答评论,它们是在单独的查询中执行的。

query = query
    .FetchMany(x => x.Answers);

如果 NHibernate 只能在两个级别上很好地完成工作 FetchMany 仅具有两个关系,为什么还要创建 ThenFetchMany(在三个级别上使用,但有错误,有重复的对象)?事实上,如果你想在三个关系上也使用它,即使 FetchMany 也是无用的,它也会产生重复的对象。

NHibernate 团队是否会因为 ThenFetchMany 无法正常工作而费心删除它?

当我删除获取策略时,我的映射没有错误,一切正常(即不会产生重复的对象)。

最佳答案

要获得独特的结果

对于 Linq:

.Distinct()

用于查询

.TrasformUsing(Transformers.DistinctRootentity)

标准

.SetResulttransformer(Transformers.DistinctRootentity)

编辑:实际上这是NH的一个缺点,它会产生笛卡尔积,但这可以改进

repo.All.Where(y => y.QuestionId == id)
        .FetchMany(x => x.Answers)
            .ThenFetchMany(x => x.Comments)
        .Future()

query = repo.All.Where(y => y.QuestionId == id)
        .FetchMany(x => x.Comments)

var result = query.AsEnumerable().Single();

参见http://ayende.com/blog/4367/eagerly-loading-entity-associations-efficiently-with-nhibernate

看起来有点奇怪,但应该可以

关于nhibernate - NHibernate FetchMany 在两个以上的表上是否损坏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7028705/

相关文章:

php - 什么 PHP ORM 最像 NHibernate?

wpf - Entity Framework CTP5 代码优先,WPF - MVVM 建模

c# - 在 NHibernate 中动态引用属性?

c# - 如何在请求结束时在 Controller 内执行某些操作?

c# - 如何在 EF 5 中导入具有标量返回值的函数

c# - .Net Core 2.1 似乎忽略了 modelBuilder.Entity<TEntity>().HasData

c# - 在 Entity Framework 6.1 中添加存储过程的问题

c# - Entity Framework 4 CRUD 创建错误

c# - 避免使用 NHibernate 实体列表进行 N+1 选择

c# - NHibernate.Mapping.ByCode.Conformist.ClassMapping 和 FluentNHibernate.Mapping.ClassMap 有什么区别?