|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
Гуглил, но, видимо, не то или не так. В общем, хотелось бы при выборке сущности или коллекции сущностей пометить их как-то только для чтения. Просто для страховки от ошибок в алгоритме. То есть, есть, к примеру, метод, который получает в распоряжение какое-то количество сущностей, меняет, скажем, только одну, и вызывает Save на контексте. Если алгоритм случайно изменил сущности, которые ему выдали в распоряжение "только для чтения", то их изменение приведет (скажем) к исключению при сохранении или еще какому-то блокирующему поведению. Есть ли в EF что-то в таком духе? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.11.2014, 20:28 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
Только AsNoTracking для всего сета. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.11.2014, 20:32 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
МСУТолько AsNoTracking для всего сета.Собственно, мне и нужно для сета. Я правильно понял, что если я сделаю MySet.AsNoTracking().SingleOrDefault(....), полученная единственная сущность также не будет отслеживаться контекстом? Я правильно понял, что я не получу исключения при сохранении, просто изменения таких сущностей будут проигнорированы? Есть ли какие-то неприятные побочные явления у этого метода (ну типа, материализация, производительность и т.п.)? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.11.2014, 20:43 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
Shocker.ProЯ правильно понял, что если я сделаю MySet.AsNoTracking().SingleOrDefault(....), полученная единственная сущность также не будет отслеживаться контекстом? Да. Shocker.ProЯ правильно понял, что я не получу исключения при сохранении, просто изменения таких сущностей будут проигнорированы? Да. Shocker.ProЕсть ли какие-то неприятные побочные явления у этого метода (ну типа, материализация, производительность и т.п.)? Наоборот, при отключенном трекинге производительность выше. Можно влиять на трекинг либо на уровне сетов через AsNoTracking, либо на уровне всего контекста через AutoDetectChangesEnabled. Иметь же один сет с вперемешку включенным и отключенным трекингом на уровне отдельных сущностей нельзя. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.11.2014, 21:40 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
Спасибо. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.11.2014, 00:33 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
Shocker.Pro, ObjectContext.SavingChanges event в http://msdn.microsoft.com/ru-ru/library/system.data.objects.objectcontext.savingchanges(v=vs.110).aspx как раз подходящий пример, который производит валидацию и выкидывает exception. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.12.2014, 18:04 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
спасибо, гляну ... |
|||
:
Нравится:
Не нравится:
|
|||
01.12.2014, 18:06 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
Gluck_13Shocker.Pro, ObjectContext.SavingChanges event в http://msdn.microsoft.com/ru-ru/library/system.data.objects.objectcontext.savingchanges(v=vs.110).aspx как раз подходящий пример, который производит валидацию и выкидывает exception. Это да, но зачем эту сущность вообще отслеживать в трекере? ... |
|||
:
Нравится:
Не нравится:
|
|||
01.12.2014, 20:44 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
Еще проблемка. Пытаюсь получить доступ к измененным сущностям перед тем, как вызову SaveChanges() Код: c# 1. 2. 3. 4.
Пока в контексте не было NoTracking объектов, этот код работал, когда они там стали появляться, метод Entries генерит исключение:The object in the ' мой_notracking_тип ' role cannot be automatically added to the context because it was retrieved using the NoTracking merge option. Explicitly attach the entity to the ObjectContext before defining the relationship.не догоняю, что мне с этим сделать, как получить список измененных сущностей ... |
|||
:
Нравится:
Не нравится:
|
|||
03.02.2015, 13:39 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
Shocker.Pro, Рекомендую забыть про AsNoTracking. Чтобы получать сущности только для чтения, просто воспользуйся отражением, и будет счастье: Код: c# 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. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43.
Вот и всё. Плюсы -- не надо ковырять EF и его потроха, независимость от источника данных (в целом, это вообще может быть не DbContext, а простой List, что очень удобно для юнит-тестов, или вообще что-то другое, лишь поддерживало IQueryable), ты получаешь только те данные, что тебе надо (именно тот набор полей) и не можешь ничего изменить случайно ни при каких обстоятельствах, т.е. без всяких допущений, что там дескать должен работать AsNoTracking. Считаю, что AsNoTracking-у место только в узкоспециализированных решениях, в разработке прикладных со слоем бизнес-логики от него в итоге больше проблем, чем пользы. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.02.2015, 14:26 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
Разобрался через ObjectContext.ObjectStateManager.GetObjectStateEntries Только нифига не понял, мой контекст наследует DbContext-у DbContext реализует IObjectContextAdapter, таким образом должен иметь свойство ObjectContext Однако, Intellisense мне его не выдает, пока я явно не приведу db к IObjectContextAdapter, компиляция тоже не проходит без приведения, почему так? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.02.2015, 14:37 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
hVostt, Доводы ясны, но есть другие соображения, о них позже. Подскажи тогда плиз, как правильно сделать. У сущности есть навигационное свойство "многие-ко-многим", в виде virtual List<MyEntityType> При создании/редактировании экземпляра сущности, у меня есть коллекция id-шников внешнего ключа. Как мне правильно заполнить это свойство? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.02.2015, 14:48 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
Похоже, список MyEntityType при редактировании отношения многие-ко-многим нельзя получать AsNoTracking, ибо они тоже должны сохраняться (хотя фактически происходит перезапись только таблицы отношений, но для EF сущности "на том конце" считаются как бы модифицированными) ... |
|||
:
Нравится:
Не нравится:
|
|||
03.02.2015, 14:53 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
Shocker.ProОднако, Intellisense мне его не выдает, пока я явно не приведу db к IObjectContextAdapter, компиляция тоже не проходит без приведения, почему так? Потому что интерфейс реализован явно (explicit) (т.е. требуется приведение к интерфейсу). Shocker.ProПодскажи тогда плиз, как правильно сделать. У сущности есть навигационное свойство "многие-ко-многим", в виде virtual List<MyEntityType> При создании/редактировании экземпляра сущности, у меня есть коллекция id-шников внешнего ключа. Как мне правильно заполнить это свойство? Возможно это покажется неудобным, но с помощью одного ключа добавить связь так просто не удастся. Требуется получить экземпляр сущности, затем добавить в коллекцию. Другой способ (которым лучше не пользоваться), это создать новый экземпляр с нужным Id (остальные поля определять не надо), приатачить его к контексту , затем добавит в коллекцию навигационного свойства. Я стараюсь избегать нативной реализации М:М, предлагаемой EF. Вместо этого я сам определяю таблицу двухсторонней связи, это хорошо тем, что контроля больше, в связь можно добавить атрибуты (хотя бы даже время установки связи и кем она сделана), и не надо так морочиться, можно использовать чистые Id, без свистоплясок. Но если такой возможности нет, то как я сказал выше. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.02.2015, 16:31 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
hVosttи не надо так морочитьсяНу, хорошо, у тебя есть лишняя сущность - связка. А => ММ <= Б Таким образом, при перезаписи сущности А тебе не надо дергать сущности Б. Нужно грохнуть все сущности ММ, связанные с А, создать новую коллекцию сущностей ММ (ссылка на Б прописывается через ММ.Б_Id) Как вариант, грохнуть только удаленные сущности ММ, неизменившиеся подгрузить и добавить только новые. Ну и обслуживать эти связки их нужно, создавать, управлять.... Вроде как, мороки больше. Опять же, ты же вроде сторонник по максимуму использовать возможности EF )) ... |
|||
:
Нравится:
Не нравится:
|
|||
03.02.2015, 16:57 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
Shocker.ProНу и обслуживать эти связки их нужно, создавать, управлять.... Не нужно обслуживать эти связки, работаешь с ними точно также, через навигационные свойства. Просто по сути, связь это тоже своего рода объект. Она тоже может обладать атрибутами. Допустим, у товара есть аналоги и рекомендованные для покупки с ним товары. По определению аналог не может быть рекомендованным товаром, следовательно задача решается всего одной связью с типом связи, а не двумя отдельными, за которыми придётся дополнительно следить. Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
Составной ключ, такой же как и в «нативной» М:М, что значит каскад и отдельного сопровождения не требуется. Такой способ связи проще развивать. Например, можно связи физически не удалять, сохраняя историю, сохранять информацию о дате создания и пользователе, создавшем связи и другую мета-информацию, расширять типы связей, получая таким образом больше контроля над данными. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.02.2015, 21:47 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
hVosttпросто воспользуйся отражениемА вот скажи, как ты поступаешь, когда членов много? Используешь какой-то кодогенератор? А при модернизации сущности? Например, у меня есть сущность с кучей свойств, которые все мне нужны, я просто получил ее и начал обрабатывать (допустим заказ) Но вот мне нужно одно свойство из другой связанной сущности (к примеру, мне нужны все поля заказа и еще имя клиента (без остальных свойств клиента)). Если я заранее сделаю Include, загрузится весь клиент, который мне не нужен, хотя и в одном запросе к БД. Если я дерну его имя через навигационное свойство - опять же загрузится клиент целиком, да еще и отдельным запросом к БД. Если я изначально сделаю проекцию - это будет оптимально для работы с БД, но тогда мне придется перестраивать проекции всякий раз, когда я модернизирую сущность заказа. ЗЫ: Дополнительный вопрос - в твоем примере с автомаппером - сработает ли оптимизация, и данные разных сущностей из БД будут получены одним запросом с join-ом? ... |
|||
:
Нравится:
Не нравится:
|
|||
12.02.2015, 20:54 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
hVostt, и тут миграцию хотят :) да уж ефчик - неужто так трудно галочку поставить - ридонли для чего то там :( ... |
|||
:
Нравится:
Не нравится:
|
|||
12.02.2015, 22:41 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
Shocker.ProЕсли я изначально сделаю проекцию - это будет оптимально для работы с БД, но тогда мне придется перестраивать проекции всякий раз, когда я модернизирую сущность заказа. Это будет не только оптимально для работы с БД, это будет оптимально в плане снижения зависимостей. Т.е. прикладной код работает с отражениями, они для него и есть данные в чистом виде, а каким образом нормализованы данные в БД или ещё там где-то, уже становится не так важно. Но за всё надо платить, естественно. Хотя разницы нет, если ты модернизируешь сущность заказа, это отразится во всех слоях. Когда возникает потребность сократить монотонный труд, можно написать кодогенерацию. В любом случае, офигенный профит тут в строгой типизиации, и в оптимальности запросов/данных. Shocker.ProЗЫ: Дополнительный вопрос - в твоем примере с автомаппером - сработает ли оптимизация, и данные разных сущностей из БД будут получены одним запросом с join-ом? Да, конечно. Автомаппер молодцом, пока проблем с ним небыло ) ... |
|||
:
Нравится:
Не нравится:
|
|||
16.02.2015, 00:13 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
В развитие темы проекций. А как создать динамическую проекцию (чтобы EF ее нормально понял и оттранслировал)? Надо мутить с деревьями выражений или копать в сторону динамически создаваемого типа через рефлексию? Или есть какой-то более простой способ? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.02.2015, 21:29 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
Shocker.ProВ развитие темы проекций. А как создать динамическую проекцию (чтобы EF ее нормально понял и оттранслировал)? Надо мутить с деревьями выражений или копать в сторону динамически создаваемого типа через рефлексию? Или есть какой-то более простой способ? В смысле, динамическую проекцию? Выбрать разные наборы полей по условию? Или как? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.02.2015, 22:13 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
Да, как-то нечетко сформулировал. Пожалуй, что вопрос даже на два пересекающихся распадается: 1) Как в рантайме создать проекцию из произвольного набора полей. Например автомаппер с его Project().To() не знает заранее набор полей для проекции, он его формирует на основе созданной в рантайме карты динамически - как? 2) Select(n => new { ... }) какие конструкции можно подсовывать в EF вместо "new { ... }" или "new MyPOCO() {...}", чтобы EF составил плоскую проекцию и выбрал все одним запросом? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.02.2015, 22:29 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
Shocker.Pro1) Как в рантайме создать проекцию из произвольного набора полей. Например автомаппер с его Project().To() не знает заранее набор полей для проекции, он его формирует на основе созданной в рантайме карты динамически - как? Произвольный набор полей, это что? Как раз таки Project().To() заранее знает набор полей, так как при компиляции тип определён, набор свойств типа известен, кроме того должен быть определён маппинг для типа. Или ты имеешь в виду некий нетипизированный датасет? Shocker.Pro2) Select(n => new { ... }) какие конструкции можно подсовывать в EF вместо "new { ... }" или "new MyPOCO() {...}", чтобы EF составил плоскую проекцию и выбрал все одним запросом? либо new {}, либо new MyPOCO {}. Сам по себе EF плоскую проекцию не создаёт, а вот AutoMapper умеет, если придерживаться соглашений . Или ты имеешь в виду нечто типа SELECT *, и получить набор полей, имеющихся в БД? Просто не понимаю, куда это должно замаппиться, типа анонимный класс, созданный динамически на основе полученного набора? Не уверен, что в этом есть смысл, а на деле не помню, чтобы кто-то такое поддерживал. Технически для подобного результата надо будет мутить с рефлекшеном и эмитить код. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2015, 00:11 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
hVosttКак раз таки Project().To() заранее знает набор полей, так как при компиляции тип определёнПри компиляции известно, какой набор полей будет на выходе, но неизвестно, какие поля будут затребованы из БД. Допустим я в DTO-классе прописал поле CreatorName, которое автомаппером будет преобразовано как свойство Name у навигационного свойства Creator. При этом карту преобразования он ведь составляет в рантайме. То есть именно в рантайме он должен сообщить EF-у, какие поля из объектов и навигационных свойств ему нужны. Вот этот механизм я и пытаюсь понять. ======================= Я, в общем-то, хочу разобраться, как EF работает с проекцией, чтобы у себя обобщить некоторые вещи... Вот представь, на чистом SQL - есть некоторая типичная выборка из нескольких таблиц. При этом, в большинстве случаев она нужна не сама по себе, а в составе более глобальной выборки. Я создаю под нее View. Далее, когда мне нужна какая-то конкретная выборка, я сделаю селект из нужной таблицы и джойню необходимую вьюшку (или несколько). Тем самым, во View я инкапсулирую повторный код. Соответственно, тут я хочу сделать что-то подобное - то есть не создавать под каждый чих конкретный набор полей, а использовать комбинацию готовых наборов что ли... В общем сделать шаг к обобщению и инкапсуляции. То есть, к примеру, у меня есть базовый DTO класс, но, используя его для проекции, я хочу в конкретных случаях присоединить еще пару полей (из связанных таблиц в том числе) и при этом не городить ветвистые деревья DTO-классов. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2015, 00:41 |
|
EF: Защитить сущность от изменений
|
|||
---|---|---|---|
#18+
Shocker.Pro, Прочитал ветку до конца, потом поднялся опять в начало - Вы что там программируете-то? Нейронные сети с нечеткой логикой? Что-то прочитать из контекста, что-то записать в контекст, но только то, что нужно, а то что не нужно - не надо, а если всё-таки - то уронить то, что уронится? Чудно право. -- Просто для страховки от ошибок в алгоритме. Сказано вслух. И все обсуждают. Алгоритмы надо проектировать без ошибок. Чай не в яваскрипте массивы лепим. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2015, 00:50 |
|
|
start [/forum/topic.php?fid=17&msg=38880316&tid=1349614]: |
0ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
144ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
59ms |
get tp. blocked users: |
1ms |
others: | 12ms |
total: | 260ms |
0 / 0 |