鉴于此:
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/