Biorąc pod uwagę to:Czy NHibernate FetchMany na więcej niż dwóch stołach jest zepsuty?
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 nie produkują duplikaty obiektów na Odpowiedź, QuestionComment, AnswerComment podczas NHibernate robi.
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();
}
produkuje to również duplikaty obiektów (głęboki trzy poziomy, stosując trzy relacje): (głęboko tylko dwa poziomy, ale za pomocą trzech relations)
query = query
.FetchMany(x => x.Answers)
.ThenFetchMany(x => x.Comments)
ta produkuje także duplikaty obiektów:
query = query
.FetchMany(x => x.Answers)
.FetchMany(x => x.Comments);
Nie powoduje to duplikowania obiektów, jednak szybkie ładowanie ma tylko dwa poziomy głębokości i dwie relacje, tj. Od pytania do odpowiedzi. W przypadku komentarzy, które należy zadać, oraz komentarzy do odpowiedzi, są one wykonywane w oddzielnym zapytaniu.
query = query
.FetchMany(x => x.Answers);
Jeśli NHibernate może jedynie wykonywać swoje zadania dobrze na dwóch poziomach FetchMany tylko z dwóch relacji tylko, po co tworzących ThenFetchMany (używany na trzech poziomach, ale ma błąd, ma duplikatów obiektów)? W rzeczywistości, nawet FetchMany jest bezużyteczne, jeśli chcesz używać go również na trzech relacjach, tworzy również duplikaty obiektów.
Czy zespół NHibernate może być przeszkadzający w usunięciu funkcji ThenFetchMany, ponieważ nie działa poprawnie?
Nie ma błędu w moim mapowaniu, rzeczy działają prawidłowo (tzn. Nie tworzą duplikatów obiektów) po usunięciu strategii pobierania.
możesz zrobić, co chcesz - dodaj '.TrasformUsing (Transformers.DistinctRootentity)'. to jest denerwujące. – Firo
Jest to dostępne tylko w QueryOver, ale używam Linq (IQueryable) NH. Jaka jest metoda rozszerzenia NH Linq odpowiednik '.TransformUsing'? –
Dzieje się tak, ponieważ Entity Framework tworzy zapytanie za pomocą niektórych UNION, podczas gdy NHibernate wykonuje JOIN. JOIN powoduje produkty kartezjańskie, a więc duplikaty. Strategia EF jest w tym przypadku lepsza, ponieważ pozwala uzyskać wiele informacji w jednym zapytaniu. – Sebazzz