问题
I have this
using (ITransaction transaction = session.BeginTransaction())
{
Task tAlias = null;
CompletedTask cAlias = null;
List<Task> tasks = session.QueryOver<Task>(() => tAlias)
.Where(Restrictions.In(Projections.Property(() => tAlias.Course.Id), courseIds))
.Fetch(pt => pt.PersonalTaskReminders).Eager
.List<Task>().ToList().ConvertToLocalTime(student);
transaction.Commit();
return tasks;
}
PersonalTaskReminders == Collection
So a task can have many personalTaskReminders. I am finding though if I set 2 personalTaskReminders(so PersonalTaskReminders will now have 2 rows in it's collection from the db)
That it returns the same task twice.
So if I had 50 personaltaskReminders for that task. I would get 50 results of the same task. I don't understand why.
If I remove the eager loading. I get the one task back from the database as I expected.
回答1:
It is obvious, because eager fetch causes join with 2 tables. To get rid of duplicated results you should use DistinctRootEntityTransformer.
By the way, NHibernate offers much nicer syntax for IN
clause. So your query should look like this:
var tasks = Session.QueryOver<Task>()
.WhereRestrictionOn(x => x.Id).IsIn(courseIds)
.Fetch(pt => pt.PersonalTaskReminders).Eager
.TransformUsing(Transformers.DistinctRootEntity)
.List<Task>();
回答2:
Xelibrion's solution is the right way to fix the problem.
To understand why the results are duplicated when doing Fetch
, you can compare the generated SQL:
Without Fetch
the fields in the SELECT
are just your root entity Task
fields.
With Fetch
the fields of PersonalReminder
entities have been added to the SELECT
. So if you have two PersonalReminder
registers for the same Task
you get two registers in the results, and a DISTINCT
clause would not remove them (as the real returned registers are different because they contain the PersonalReminder
fields).
The SQL generated with and without TransformUsing
is exactly the same, but NH processes the returned registers to remove the duplicates.
来源:https://stackoverflow.com/questions/6221362/am-i-doing-something-wrong-with-nhibernate-query-over-fetch