2013-08-28 2 views
0

Хорошо, скажем, у меня есть объекты «Многие-ко-многим», «Студент/класс». При следующем отображенииУкажите глубину ассоциации в критериях Nhibernate

 HasManyToMany(m => m.Classes) 
       .Table("StudentClasses") 
       .LazyLoad() 
       .Cascade.None(); 

и запроса:

 return _session.CreateCriteria<Student>() 
           .Add(Restrictions.Eq("Id", studentId)) 
           .SetCacheable(false) 
           .UniqueResult<Student>(); 

Мои Таблицы

ID | Student   ID | Class    StudentId | ClassId 
    ============   ===========    =================== 
    1 | John    1 | Algebra    1   | 1 
    2 | Sue    2 | Biology    1   | 2 
    3 | Frank    3 | Speech    2   | 2 
    4 | Jim    4 | Athletics   2   | 5 
    5 | Frankenstein  5 | History    5   | 5 

То, что я хочу Джон, с алгебры и биологии Это приходит, Но биология приходит с Джоном и Сью, она, в свою очередь, получает меня Bio и History, которая заполняет иск и Франкенштейна. Вы не хотите получать Франкенштейна (или что-то, что выходит за рамки биологии). Также в любой момент вы можете начать круговое движение кругами.

Как указать, чтобы не заполнить это глубоко? SetMaxRows, очевидно, не хочет, я ищу, поскольку он сокращает общее количество строк, я только хочу увлажнить первый уровень. Я особенно смущен, потому что думал, что LazyLoading заставит меня точно указать, что я хотел увлажнить.

+0

Откуда вы знаете, что Джон и Сью тоже возвращаются? –

ответ

1

Lazy loading позволяет вам не должен указать, что вы хотите увлажнить. Коллекции будут заполняться «лениво» во время доступа к ним. В приведенном выше запросе вы получите только одну строку: Джон. Когда вы обращаетесь к john.Classes, NHibernate выполнит другой запрос за кулисами, чтобы получить классы Джона. Затем, когда вы получаете доступ к свойству biology.Students, NHibernate выполнит другой запрос для заполнения этой коллекции ... и так далее.

Вы определенно делаете хотите lazy-load on this relationship (что по умолчанию, кстати). Если бы вы отказались от ленивой загрузки, тогда это сделало бы именно то, что вы говорите, чего хотите избежать - NHibernate будет знать, что им не разрешено лениво загружать эти коллекции, поэтому он начнет работать, чтобы загрузить их, как только вы загрузили ученика , что потенциально может привести к загрузке всех данных в этих трех таблицах и очень неэффективно с большим количеством обращений к базе данных.

Если вы знаете, что все, что вы хотите, это «Джон, с алгеброй и биологией», то вы должны добавить эти строки запроса:

.SetFetchMode("Classes", FetchMode.Eager) 
    .SetResultTransformer(Transformers.DistinctRootEntity) 

SetFetchMode говорит NHibernate использовать левое внешнее присоединяется к предварительно заполнить коллекцию student.Classes. DistintRootEntity сообщает NHibernate не возвращать дубликатов студентов, которые будут сгенерированы левым внешним соединением.

Смежные вопросы