Am I doing something wrong with Nhibernate Query Over fetch?

限于喜欢 提交于 2019-12-22 10:23:44

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!