|
NHIbernate: коллекции равны null у proxy
|
|||
---|---|---|---|
#18+
Добрый день, уважаемые! Очень были бы рады помощи в решении такой проблемы, уже давно возникающей: Есть entity Organization. У нее есть потомок ТакаяТоOrganization. В потомке две коллекции, вот та из них, от которой проблемы: Код: plaintext 1. 2. 3. 4. 5.
маппинг, экспортированный Fluent (коллекция попала в маппинг предка, в ветку <joined-subclass>): Код: plaintext 1. 2. 3. 4. 5. 6.
В конструкторе Contract вызывается метод изменения коллекции, принадлежащей ТакаяТоOrganization: Код: plaintext
Самое странное - смотрим в отладчике MSVS коллекцию public (Contracts), видны в ней договора. Смотрим поле _contracts, из которого собственно и читается она - у прокси она null. Как бы не работает Lazy Load в таком случае, выходит. Как быть? ... |
|||
:
Нравится:
Не нравится:
|
|||
01.06.2011, 18:39 |
|
NHIbernate: коллекции равны null у proxy
|
|||
---|---|---|---|
#18+
Собственно, пока нашел 4 варианта ответов а) GetConcrete() у организации, возвращающий null (этот класс абстрактный), и его реализации, возвращающие this, у потомков. б) переписать методы - лишить другие классы доступа к коллекции. Тогда упростится и маппинг. в) вызвать NHibernat-овский метод, который может распроксить объект (где-то, помню, обсуждался, решили, что GetConcrete() лучше). г) сделать третье поле, которое будет возвращать не ImmutableSet<Contract>, а непосредственно _contracts. Громоздко. Как лучше, или, может, еще как-то? ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2011, 09:59 |
|
NHIbernate: коллекции равны null у proxy
|
|||
---|---|---|---|
#18+
NHibernate_User_Как бы не работает Lazy Load в таком случае, выходит. Угадаете, как отладчик смотрит коллекцию? NHibernate_User_б) переписать методы - лишить другие классы доступа к коллекции. Тогда упростится и маппинг. Единственно верная мысль, я вам ее уже говорил. Коллекция - собственность класса. Изменения членов только через методы add/remove. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2011, 10:23 |
|
NHIbernate: коллекции равны null у proxy
|
|||
---|---|---|---|
#18+
простейший вариант вдогонку. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26.
Целуйтесь по возможности :) ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2011, 10:33 |
|
NHIbernate: коллекции равны null у proxy
|
|||
---|---|---|---|
#18+
Спасибо, хотя у нас М:М. Я вижу, поле Org в Contract не зазорно переписывать из другого объекта? Тут встает вопрос, как нам не спутать и не вызвать метод по ошибке не тот? Скажем, надо полностью разорвать связь, Organization.DeleteContract() убирает контракт из своей коллекции contracts, а потом для убирания организации из коллекции организаций внутри контракта вызывает Contract.DeleteOrganization. Которая уже ничего не вызывает, а только чистит свою коллекцию. Т.е. первый метод чистит две коллекции - свою и чужую (через второй) - а второй только свою. Что, если программист ошибется и вызовет в контроллере (MVC) или еще где-то вместо первого метода второй? Называются-то они одинаково. Тот не почистит обе коллекции (только одну), и в той же сессии кто-то может успеть прочитать коллекцию с "фантомным" как бы значением. Если для удаления еще могу придумать разные названия: Delete и Remove, то как с добавлением быть? AddContract и DobavitOrganization? :) Ну и protected internal сделать у "внутренних" методов, т.е. которые только одну коллекцию чистят. Придумал еще вариант, у него, конечно, минус, что вся коллекция пройдется (хотя бы id-ы будут прочитаны), но тем не менее она и так (при collection.Remove) пройдется, как я понимаю. Примерно как Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25.
Кстати сказать, Вы бы использовали collection.Contains() или linq с лямбдой? Нет ли статей по реализации М:М по-нормальному? Сколько ни смотрю примеров, везде всё public! Хотя бы тут... Мне бы несколько вариантов реализаций М:М в NHibernate от разных авторов, но увы - ищу, ищу, а там все (от мегаразработчиков-глав до студентов) в примерах используют public... ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2011, 12:02 |
|
NHIbernate: коллекции равны null у proxy
|
|||
---|---|---|---|
#18+
Что-то все же непонятное. >Угадаете, как отладчик смотрит коллекцию? Нет, не угадаю. Попытался сделать метод внутри entity для работы с ее же коллекцией Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9.
Не только в отладчике коллекция null, но и он кидает exception "Object reference not set to an instance of an object." на строке Add(contract). А public коллекция почему-то не Null. Почему так. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2011, 16:33 |
|
NHIbernate: коллекции равны null у proxy
|
|||
---|---|---|---|
#18+
Может, в маппингах все дело. В книге NH CookBook вроде пример маппинга в связи 1:М (на стороне М) просто как Код: plaintext
А у нас на стороне М: Код: plaintext
Код: plaintext 1. 2.
в примере на стороне 1: Код: plaintext 1. 2. 3. 4.
у нас: Код: plaintext 1. 2.
Код: plaintext 1. 2. 3. 4. 5.
... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2011, 18:31 |
|
NHIbernate: коллекции равны null у proxy
|
|||
---|---|---|---|
#18+
Такое впечатление, что NHibernate не дружит с protected internal. Заменил protected internal на public, все заработало. public /*protected internal*/ virtual void AddContract(Contract contract) Весь тщательно спроектированный домен будет разваливаться по швам из-за этих public .... :( ... |
|||
:
Нравится:
Не нравится:
|
|||
02.06.2011, 19:53 |
|
|
start [/forum/topic.php?fid=17&msg=37290736&tid=1350758]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
142ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
40ms |
get tp. blocked users: |
1ms |
others: | 293ms |
total: | 514ms |
0 / 0 |