两张以上桌子上的NHibernate是否损坏?

两张以上桌子上的NHibernate是否损坏?,nhibernate,entity-framework,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]

鉴于此:

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; }
    }

}
这也会生成重复对象(仅两层深,但使用三种关系):

这不会产生重复的对象,但是急切加载只针对两个层次和两个关系,即从问题到答案。对于要提问的注释和要回答的注释,它们在单独的查询中执行

query = query
    .FetchMany(x => x.Answers);
如果NHibernate只能对两个级别的FetchMany做好它的工作,那么为什么还要费心创建FetchMany(用于三个级别,但有错误,有重复的对象)?事实上,即使FetchMany也没用如果你想在三个关系上使用它,它也会产生重复的对象

NHibernate团队会因为无法正常工作而费心删除许多吗

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

尝试:

    query.QueryOptions.RegisterCustomAction(c => c.SetResultTransformer(new DistinctRootEntityResultTransformer()));

要获得独特的结果,请执行以下操作:

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


它看起来有点奇怪,但应该做

你可以做你想做的事-append
.TrasformUsing(Transformers.distinctroventy)
。这当然很烦人。这只在QueryOver上可用,但我使用的是NH的Linq(IQueryable)。NH Linq扩展方法与
.TransformUsing
等效于什么?这是因为实体框架使用一些联合创建查询,而NHibernate执行连接。连接产生笛卡尔积,从而产生重复实体。在这种情况下,EF的策略更好,因为它允许在一个查询中获得更多信息。这仅在NH2.0 Linq上可用。在NH3.0上,Linq丢失了。在NH3.0中,Linq没有丢失。它有自己的LINQ提供商。您可以通过.Query访问它。您可以在QueryOver上使用变压器。但是,在一个查询中不应该多次使用FetchMany。是的,我知道,NHibernate 3支持LINQ,它可以通过.query访问,在LINQ 2上,它在.LINQ上。事实上,自从我开始使用NH以来,我只通过HQL和Linq进行查询(现在专门处理这个问题,不喜欢HQL magic string)。我只是将
.Query
放在我的存储库界面的
All
属性中。我的意思是NH3.0LINQ上的
,它丢失了
,我只是忘了在单词Linq和它之间加一个逗号;-)它是:
QueryOptions.RegisterCustomAction
.TrasformUsing(Transformers.DistinctRootentity)
.SetResulttransformer(Transformers.DistinctRootentity)
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();