|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
Добрый день! Разбираюсь с EF (раньше не работал) и выполняю примеры. Везде стандартным является пример "Клиент и его Заказы". Промеры везде доводятся до внесения информации в таблицу Customers и на этом всё заканчивается. Я решил пойти дальше и занести хотя бы один заказ, который делает клиент и ... ничего не получилось. Выдаётся ошибка. Что я не так делаю? Вот примитивная программа: Код: 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. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61.
Ничего хитрого - всё как в учебниках! При выполнении первого фрагмента с Customers база прекрасно создаётся (SQLEXRESS), клиент вносится, читается, однако задать ему заказ не получается - см. рисунок. В чём проблема? С уважением ВВГ ... |
|||
:
Нравится:
Не нравится:
|
|||
28.10.2016, 10:39 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
ValGer Код: c# 1.
Ты забыл добавить virtual. Если в учебниках этого нет, то это плохие учебники. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.10.2016, 10:49 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
hVostt, В учебнике (professorWeb.ru) этого действительно нет, но я внёс по вашей рекомендации и ничего не изменилось. Та же самая ошибка (см. рисунок выше) Код: c# 1. 2. 3. 4. 5. 6. 7. 8.
... |
|||
:
Нравится:
Не нравится:
|
|||
28.10.2016, 11:27 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
ValGer Код: c# 1. 2. 3. 4. 5.
Добавить virtual -- это правильно и будет работать для объектов извлечённых из БД. Но тут сам смотри что происходит. Ты создал новый Order, а ссылку на Customer не присвоил. Надо так: ValGer Код: c# 1. 2. 3. 4. 5. 6.
... |
|||
:
Нравится:
Не нравится:
|
|||
28.10.2016, 11:46 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
hVostt, Помогло, спасибо большое! Может смысл virtual поясните - пока не очень понимаю для чего он тут нужен! С уважением ВВГ ... |
|||
:
Нравится:
Не нравится:
|
|||
28.10.2016, 12:07 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
hVostt Ты забыл добавить virtual. Если в учебниках этого нет, то это плохие учебники. А не ошибка ли дизайна EF использование virtual? Не правильнее ли было использовать атрибут? ... |
|||
:
Нравится:
Не нравится:
|
|||
28.10.2016, 12:32 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
ValGerhVostt, Помогло, спасибо большое! Может смысл virtual поясните - пока не очень понимаю для чего он тут нужен! С уважением ВВГ Когда вы извлекаете объекты из БД вот так: ValGer Код: c# 1. 2.
То навигационные свойства, помеченные как virtual будут доступны. А без virtual они всегда будут null. Это называется ленивое извлечение данных. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.10.2016, 12:36 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
ЕвгенийВhVosttТы забыл добавить virtual. Если в учебниках этого нет, то это плохие учебники. А не ошибка ли дизайна EF использование virtual? Не правильнее ли было использовать атрибут? Не ошибка дизайна, а необходимость. Без virtual ты никак не сделаешь ленивое извлечение данных, никакие атрибуты тебе не помогут. Но если не добавлять virtual, данные по навигационным полям можно извлекать только с помощью жадной загрузки. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.10.2016, 12:37 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
Уважаемый hVostt , прошу Вас помочь с решением похожей проблемы. Ссылка . Спасибо ... |
|||
:
Нравится:
Не нравится:
|
|||
28.10.2016, 12:46 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
hVostt Не ошибка дизайна, а необходимость. Без virtual ты никак не сделаешь ленивое извлечение данных, никакие атрибуты тебе не помогут. Но если не добавлять virtual, данные по навигационным полям можно извлекать только с помощью жадной загрузки. Типа делает наследника в котором переопределяет свойство с использованием отложенной загрузки? ... |
|||
:
Нравится:
Не нравится:
|
|||
28.10.2016, 13:11 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
ЕвгенийВhVosttНе ошибка дизайна, а необходимость. Без virtual ты никак не сделаешь ленивое извлечение данных, никакие атрибуты тебе не помогут. Но если не добавлять virtual, данные по навигационным полям можно извлекать только с помощью жадной загрузки. Типа делает наследника в котором переопределяет свойство с использованием отложенной загрузки? Ага. Это называется прокси-объект. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.10.2016, 13:32 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
hVosttЕвгенийВпропущено... Типа делает наследника в котором переопределяет свойство с использованием отложенной загрузки? Ага. Это называется прокси-объект. вроде в NH обязательность virtual убрали ... |
|||
:
Нравится:
Не нравится:
|
|||
29.10.2016, 12:15 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
ЕвгенийВhVosttТы забыл добавить virtual. Если в учебниках этого нет, то это плохие учебники. А не ошибка ли дизайна EF использование virtual? Не правильнее ли было использовать атрибут? конечно ошибка ... |
|||
:
Нравится:
Не нравится:
|
|||
29.10.2016, 12:20 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
fsharp_fsharphVosttпропущено... Ага. Это называется прокси-объект. вроде в NH обязательность virtual убрали Что такое NH? ... |
|||
:
Нравится:
Не нравится:
|
|||
30.10.2016, 10:32 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
fsharp_fsharpвроде в NH обязательность virtual убрали В EF virtual тоже не обязателен. Изначально. При чём очень-очень многие «понаехавшие» в разработку на EF из NH, проставляют virtual всем полям подряд, даже не навигационным. Вот это и есть глобальная ошибка дизайна NH, погубившая многие умы. fsharp_fsharpконечно ошибка Ошибка фигачить virtual на все поля. Ошибка не понимать, для чего он нужен. А так, это языковое средство, которое правильно используется, при правильном понимании. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.10.2016, 12:03 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
ValGerЧто такое NH? NHibernate. Поделие с очевидным концом. В своё время был мастхев, но после выхода EF 4 и дальнейшим его развитием, стал абсолютно не нужен. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.10.2016, 12:04 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
hVosttValGerЧто такое NH? NHibernate. Поделие с очевидным концом. В своё время был мастхев, но после выхода EF 4 и дальнейшим его развитием, стал абсолютно не нужен. Ага, понятно, спасибо! Тут наткнулся в MSDN на пример и там для связанной таблицы (Order) поле связи определяется как обычным образом, так и с virtual-описателем. При этом после генерации таблицы получаем стандартное поле для связи (см. рисунок) Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9.
То есть, определений в классе 4, а полей в результирующей таблице 3 - virtual исчезает, но оставляет след в виде FK. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.10.2016, 12:36 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
ValGerПри этом после генерации таблицы получаем стандартное поле для связи (см. рисунок) На самом деле это поле не обязательно. Достаточно одного навигационного, а поле EF создаст сам. Правда в таком случае нельзя будет задавать связь с помощью ID, необходимо будет найти запись предварительно и сохранить её в навигационном поле. Это более надёжно, но менее удобно. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.10.2016, 13:38 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
hVostt, Заметил ещё одну вещь - при генерации таблиц строковые поля таблиц получают свойство "Допускает значение NULL = True", а числовые и дата, как правило, имеют установку "... NULL = False". Если такие установки по умолчанию нас не устраивают, то как их можно поменять? Для NULL = True, наверно можно пометить свойство класса в коде программы аннотацией [Required], а как сделать для NULL = False? Я попробовал после генерации поменять этот атрибут для поля прямо в таблице на сервере - всё прошло потом нормально, без "ругани" от EF, что нужно делать миграцию и т.д. и т.п. И, вообще, где можно найти достаточно полный список аннотаций? С уважением ВВГ ... |
|||
:
Нравится:
Не нравится:
|
|||
30.10.2016, 17:41 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
hVostt В EF virtual тоже не обязателен. Изначально. При чём очень-очень многие «понаехавшие» в разработку на EF из NH, проставляют virtual всем полям подряд, даже не навигационным . Вот это и есть глобальная ошибка дизайна NH, погубившая многие умы. Если у тебя хоть одно замэпленное свойство сущности (даже не навигационное) не виртуально - то прокся не будет реализовывать для нее IEntityWithChangeTracker и IEntityWithRelationships (см. код System.Data.Entity.Core.Objects.Internal.IPocoImplementor.CheckType()). Это чревато тормозами при работе с большими объектными графами в ObjectContext. Кстати, при внимательном чтении кода этого метода можно заметить еще одну тонкость, на которую мы однажды напоролись. В POCO свойства- коллекции должны быть объявлены именно как ICollection<T>. Одно время у нас коллекции были объявлены как IList<T>, в результате прокси для таких сущностей также не имплементировали IEntityWithChangeTracker и IEntityWithRelationships. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.11.2016, 17:13 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
Gluck_13Если у тебя хоть одно замэпленное свойство сущности (даже не навигационное) не виртуально - то прокся не будет реализовывать для нее IEntityWithChangeTracker и IEntityWithRelationships (см. код System.Data.Entity.Core.Objects.Internal.IPocoImplementor.CheckType()). Это чревато тормозами при работе с большими объектными графами в ObjectContext. Да ладно, гоняли какие-нибудь тесты? Сравнивали? Какие результаты? Gluck_13В POCO свойства- коллекции должны быть объявлены именно как ICollection<T>. Да, нужен именно ICollection<T>. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.11.2016, 08:46 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
ValGerЗаметил ещё одну вещь - при генерации таблиц строковые поля таблиц получают свойство "Допускает значение NULL = True", а числовые и дата, как правило, имеют установку "... NULL = False". Если такие установки по умолчанию нас не устраивают, то как их можно поменять? Для строк NOT NULL достигается с помощью атрибута [Required], или в конфигурации отображения. Для ValueType (дата/время, числа, булев) NULL достигается с помощью Nullable<T>, или модификатора «?»: Код: c# 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
02.11.2016, 08:48 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
ValGerИ, вообще, где можно найти достаточно полный список аннотаций? Я не видел места, где были бы собраны все аннотации, в документации смотреть надо. Лучше минимизировать использование атрибутов и настраивать с помощью конфигураций и конвенций. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.11.2016, 08:50 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
hVosttGluck_13Если у тебя хоть одно замэпленное свойство сущности (даже не навигационное) не виртуально - то прокся не будет реализовывать для нее IEntityWithChangeTracker и IEntityWithRelationships (см. код System.Data.Entity.Core.Objects.Internal.IPocoImplementor.CheckType()). Это чревато тормозами при работе с большими объектными графами в ObjectContext. Да ладно, гоняли какие-нибудь тесты? Сравнивали? Какие результаты? Без реализации этих интерфейсов, например, убийственно долго идет анализ изменений DetectChanges, при наличии в контексте нескольких тысяч сущностей (понятно, такого надо избегать, но иногда очень надо :)). Ситуация усугубляется с увеличением количества навигационных связей в модели. См. код в ObjectStateManager.GetEntityEntriesForDetectChanges(...) EntityEntry.SetChangeTrackingFlags() Сущности, реализующие IEntityWithChangeTracker и IEntityWithRelationships, исключаются из процесса DetectChanges(), так как прокси автоматически обрабатывает все изменения, происходящие в ней, с поддержанием актуальности реляционных связей и трекинга изменений. Если код в GetEntityEntriesForDetectChanges обнаруживает, что в контекст загружены только "правильные" прокси, то DetectChanges просто ничего не делает. Также существенно быстрее работает загрузка сущностей в контекст в режиме AppendOnly, производительность становится сопоставимой с режимом NoTracking. Когда мы привели доменную модель (около 1500 классов с большим количеством реляционных связей) в соответствие с требованиями имплементора POCO-Proxy, производительность отдельных сценариев выросла в 10 и более раз (проверялось профайлером). После этого в Сontinuous Integration были добавлены тесты, проверяющие доменную модель на соответствие этим требованиям. Проверяется, что типы не должны быть sealed, для всех свойств через Reflection вызывается метод System.Data.Entity.Core.Objects.Internal.EntityProxyFactory.CanProxySetter(), для коллекций также проверяется, что они объявлены как ICollection<T>. hVosttGluck_13В POCO свойства- коллекции должны быть объявлены именно как ICollection<T>. Да, нужен именно ICollection<T>. Тут был наш продолб, хочу просто чтоб другие не наступали на те же грабли. С другими объявлениями коллекций (например, IList<T>), на первый взгляд, вроде все работает, а потом начинают вылезать глюки, типа когда в контексте присваиваешь новому элементу из дочерней коллекции ссылку на головную сущность, она автоматически не добавляется в коллекцию головы. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.11.2016, 11:23 |
|
EF Code First - не внести данные в связанную таблицу
|
|||
---|---|---|---|
#18+
Gluck_13Без реализации этих интерфейсов, например, убийственно долго идет анализ изменений DetectChanges, при наличии в контексте нескольких тысяч сущностей (понятно, такого надо избегать, но иногда очень надо :)). Ситуация усугубляется с увеличением количества навигационных связей в модели. Согласен. Gluck_13Также существенно быстрее работает загрузка сущностей в контекст в режиме AppendOnly, производительность становится сопоставимой с режимом NoTracking. Хм. Gluck_13Когда мы привели доменную модель (около 1500 классов с большим количеством реляционных связей) в соответствие с требованиями имплементора POCO-Proxy, производительность отдельных сценариев выросла в 10 и более раз (проверялось профайлером). После этого в Сontinuous Integration были добавлены тесты, проверяющие доменную модель на соответствие этим требованиям. Проверяется, что типы не должны быть sealed, для всех свойств через Reflection вызывается метод System.Data.Entity.Core.Objects.Internal.EntityProxyFactory.CanProxySetter(), для коллекций также проверяется, что они объявлены как ICollection<T>. Мы избегаем работать с сущностями в режиме изменений, все изменения происходят на стороне, потом результат записывается в Entity и сохраняется, при чём как можно меньшими порциями. В таком режиме профита от full-proxy вряд ли получится достичь. В тех случаях когда «очень нужно», выключается автотрекинг и сигналы об изменениях пропихиваются вручную. Тоже очень быстро. Но за информацию спасибо, крайне познавательно! Gluck_13С другими объявлениями коллекций (например, IList<T>), на первый взгляд, вроде все работает, а потом начинают вылезать глюки, типа когда в контексте присваиваешь новому элементу из дочерней коллекции ссылку на головную сущность, она автоматически не добавляется в коллекцию головы. Ага, но ещё и надо понимать для чего нужен IList<> и стараться всегда юзать максимально обобщённые коллекции. IList<> нужен, если конкретно требуется индексированный доступ. В общем, тоже согласен, что надо акцентировать на этом внимание, так как очень многие грешат и IList и даже List )) ... |
|||
:
Нравится:
Не нравится:
|
|||
02.11.2016, 13:06 |
|
|
start [/forum/topic.php?fid=17&msg=39336093&tid=1349346]: |
0ms |
get settings: |
10ms |
get forum list: |
12ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
138ms |
get topic data: |
7ms |
get forum data: |
3ms |
get page messages: |
60ms |
get tp. blocked users: |
1ms |
others: | 256ms |
total: | 495ms |
0 / 0 |