Pull to refresh

Comments 23

Если не будет дальнейшего глубоко погружения, то это очередная статья «hello world EF», коих в интернете ну очень много. Продолжайте!

Если не устраивают конвенции по умолчанию, расскажите лучше как их переопределить.
Если не устраивают конвенции по умолчанию, расскажите лучше как их переопределить.

Ок, будет время — допишу прямо в статью.
Все вы так обещаете, а потом одни helloworld-ы так и остаются в сети) *вздохнул*
Если честно, для рунета технические статьи писать — дело неблагадарное. Если тема не про джаваскрипт или php, получишь 2.5 комментария, из которых 2 — критика в достаточно резкой форме.

Легче для англоязычных ресурсов писать, охват аудитории больше и люди спокойнее.
Здесь тоже люди спокойные. Пишите больше!
public class UniversityContext : DbContext
    {
        public UniversityContext() : base("UniversityContext") { }

        public DbSet<Course> Courses { get; set; }
        public DbSet<Enrollment> Enrollments { get; set; }
        public DbSet<Student> Students { get; set; }
   }

В каждом, каждом примере по Entity Framework есть эти DbSet<T> в виде свойств. И никто никогда не объясняет, зачем они нужны, и что будет, если их убрать.

System.Data.Entity.DropCreateDatabaseIfModelChanges<UniversityContext>

Это, надо заметить, очень, очень опасная настройка. Давать ее в примере, не объяснив, чем это грозит — очень недобро.

(Для тех, кто не знает: в результате этой настройки как только code-first-модель будет изменена — например, добавится новое свойство — существующая БД будет дропнута и создана заново. Да, со всеми данными.)

Ну и вообще, использовать такие инициализаторы при наличии миграций…

Во-первых, к существующей базе данных подобный подход применить сложно.

Почему?

есть так называемые конвенции, что, допустим, property который называется Id, будет по умолчанию преобразован в Primary Key таблицы

Во-первых, это легко перенастраивается. Во-вторых, даже конвенцию можно отменить.

Ну и да, это не разработка баз данных никаких боком, это разработка DAL-слоя.
Ну и вообще, использовать такие инициализаторы при наличии миграций…


Во-первых, это вводная статья. Основоное преимущество разработки с Code First — скорость Это прототип, если угодно. В нормальном приложении никто не будет писать в базу из контроллера, но для прототипов Scaffolded items неоценимы. Для прототипов инициализатор вполне сойдет.

Почему?


Как минимум потому что придется писать уродливые мапинги на существующие таблицы. Все можно сделать, вопрос — зачем.

Ну и да, это не разработка баз данных никаких боком, это разработка DAL-слоя.

Как угодно. Суть в том, что до появления реальных данных в Code First база — побочный продукт.
Для прототипов инициализатор вполне сойдет.

Вот только вы нигде не пишете, почему этот инициализатор нельзя применять в продуктивном коде. И вообще не объясняете, что он делает.

Как минимум потому что придется писать уродливые мапинги на существующие таблицы.

Это зависит исключительно от уродливости базы. А зачем — а зачем вообще использовать Code First? Вот затем же.

Суть в том, что до появления реальных данных в Code First база — побочный продукт.

Это пока вы не начинаете работать из EF-CF с существующей БД.
Вот только вы нигде не пишете, почему этот инициализатор нельзя применять в продуктивном коде. И вообще не объясняете, что он делает.

Допишу, убедили.

А зачем — а зачем вообще использовать Code First?

Главный аргумент — что разработка быстрее. Сильно быстрее. Переводить уже готовое приложение на Code First я причин не вижу. Может поделитесь?
Поделюсь: быстрее разработка, дешевле поддержка модели, проще управление версиями. Заметим, я не говорю о переводе готового приложения, я говорю о работе с существующей БД, это не одно и то же.
Заметим, я не говорю о переводе готового приложения, я говорю о работе с существующей БД, это не одно и то же.

Ок, случай достаточно типичный (в энтерпрайзе), признаю. Но при этом разработка будет медленнее, чем в когда в базе ничего ценного нет.
Разработка в любом случае будет медленнее при наличии legacy, это реальность такая. А дальше вопрос выбора инструмента, которым это удобнее делать. CodeFirst для этих целей вполне подходит, особенно при наличии генератора, который создает первоначальную схему по БД.
А можно импортировать (сгенерировать) структуру и перейти на нормальный Code First, и дропать базу, когда надо.
Вы не учитываете того факта, что в БД могут быть (а) полезные данные (например, в продуктиве) и (б) данные и объекты, которые вообще не описаны в CF.

Не говоря уже о том, что (ц) создание БД может быть долгим процессом и (д) в норме у запускаемого приложения не должно быть прав на дроп БД.
(д) в норме у запускаемого приложения не должно быть прав на дроп БД.


Если вы не поняли, я говорил про девелопера, а не про приложение.

(ц) создание БД может быть долгим процессом


Для среднестатистической CRUD аппликации он не будет долгим.

(б) данные и объекты, которые вообще не описаны в CF


Ага, значит один объект мы из кода добавляем из кода в базу, а второй из базы в код. Прямо Code First :)

(а) полезные данные (например, в продуктиве)

Девелоперу зачем «полезные данные»? Чтобы чай попить, пока апликация грузится? Для load тестирования надо отдельную среду поднимать. Я уже молчу, что если вы базу с продукции девелоперам ставите, то вам любой аудит по пальцам надает, мало не покажется.

Предлагаю прекратить спор, т.к. каждый останется при своем мнении.
Если вы не поняли, я говорил про девелопера, а не про приложение.

Database initializer у вас выполняет разработчик? Мне кажется, что все-таки приложение. Это его часть. Соответственно, у приложения должны быть эти права. У вас права приложения отличаются в продуктиве и в разработческом контуре? Вас ждут приятные новости при выкатке.

Для среднестатистической CRUD аппликации он не будет долгим.

Что такое «среднестатистическая аппликация»? Среднестатистический блог, среднестатистический энтерпрайз, среднестатический магазин? Они все очень разные.

Ага, значит один объект мы из кода добавляем из кода в базу, а второй из базы в код.

С чего вы это взяли? Мы ничего не добавляем ни в одном из направлений, у нас просто есть часть БД, с которой работает новое приложение через EF-CF, а есть часть БД, с которой работает legacy. А где-то посередине они пересекаются. Процентов на 30.

Девелоперу зачем «полезные данные»?

Я же сказал — «в продуктиве». У вас разные инициализаторы в проде и в разработческом контуре? Хорошая идея, но очень хрупкая (особенно в части «как же выкатить изменения на продуктив»).

Чтобы чай попить, пока апликация грузится?

У вас объем данных влияет на скорость каждой загрузки приложения? Печаль. Или вы говорите о времени инициализации через drop-create? Так это ваша идея, а не моя, я этого подхода рекомендовал избегать.

Я уже молчу, что если вы базу с продукции девелоперам ставите, то вам любой аудит по пальцам надает, мало не покажется.

Мы не ставим базу с продуктива разработчикам, мы используем единый код (и единый механизм версионирования) в разработческом и продуктивном контурах.

Понимаете, когда приложение, с которым вы работаете — это унаследованная учетная система со сложной структурой бизнес-данных и несколькими десятками справочников, каждый из которых может влиять на бизнес-поведение, его инициализация — это дорого.

И, собственно, я бы понял предмет этого спора, если бы в EF-CF не было миграций — но миграции решают большую часть описанных проблем (кроме прав при развертывании, но они решаются за счет явной накатки миграций разработчиком в разработческой среде и инженером развертывания в продуктиве, благо, механизм, который это позволяет, есть). Так что я, честное слово, не вижу, зачем держаться за стремительно устаревающий DropCreate кроме как в прототипах на выброс, где нет речи ни о каких реально значимых данных и хоть сколько-нибудь продолжительном сроке жизни решения.
Как минимум потому что придется писать уродливые мапинги на существующие таблицы. Все можно сделать, вопрос — зачем.

[ColumnAttribute] &nbsp?
существующая БД будет дропнута и создана заново. Да, со всеми данными.

«Все данные» — это только про «дропнута», или и про «создана заново»?

В каждом, каждом примере по Entity Framework есть эти DbSet<T> в виде свойств. И никто никогда не объясняет, зачем они нужны, и что будет, если их убрать.
Заинтриговали прямо.
А зачем они нужны и что будет, если их убрать?

Disclaimer. В этой теме я абсолютный чайник, мне просто очень интересно. Уровень вопросов моих вы уже видите. Разумеется, вы не обязаны удовлетворять мой интерес — это очевидно. Но если ответите, буду признателен :).
«Все данные» — это только про «дропнута», или и про «создана заново»?

Дропнута. Создана она будет только с теми данными, которые прошиты в Seed.

А зачем они нужны и что будет, если их убрать?

Это, на самом деле, тема для длинного рассуждения. Начнем с первой части: для чего они нужны.

Во-первых, они нужны для того, чтобы предоставить пользователю контекста доступ к коллекциям сущностям — проще говоря, context.Courses. Проблема этого подхода в том, что он осмысленен очень непродолжительное время, и как только мы начинаем либо трактовать контекст как совсем низкоуровневый доступ, скрывая его за отдельным репозиторием (в этом случае достаточно публичного Set<T>), либо трактовать его как готовый репозиторий (в этом случае наружу выставляются сразу готовые методы Get, Find и так далее, а внутри, в общем-то, тоже достаточно Set<T>). Проще говоря, у этого интерфейса неадекватный уровень абстракции.

Во-вторых, они нужны для того, чтобы контекст знал, какими, собственно, сущностями он будет пользоваться (как следствие, что создавать в БД, по чему строить миграции и так далее). Однако это поведение иногда может быть непредсказуемым, поэтому лучше всегда явно прописывать конфигурацию в OnModelCreating.

Собственно, из этого и вытекает ответ на «что будет, если»: если у вас уже прописаны все конфигурации, или классы достижимы из прописанных конфигураций по конвенциям, и вы не опираетесь на наличие у контекста именованных свойств для доступа к данным — ничего не будет. Собственно, у меня таких контекстов достаточно много, и они прекрасно работают.
Посмотри ещё на LinqConnect от Devart. мы используем его в режими Model First (Code First). Есть иногда сложности и проблемные моменты, все отражены мною у них на форуме в соответствующем разделе. Но в целом это лучшая ORM для .NET на мой взгляд. Кроме того у ни есть отличные редактор Entity Developer.
www.devart.com/linqconnect/
www.devart.com/entitydeveloper/
Асинки поддерживаются? Описание маппинга в коде без атрибутов поддерживается?
Все бы ок, но смущает что платный. И не надо про сыр, сейчас времена не те :)
Sign up to leave a comment.

Articles