Как стать автором
Обновить

Комментарии 24

Увидев картинку из своего поста на минуту испытал когнитивный диссонанс, потом вчитался и понял что это другой пост))
За статью спасибо.
Извиняюсь, картинку искал в Google, просто она самая подходящая.
Так я же не в претензии )
Главное, что статья хорошая, а рисунок не жалко )
Очень полезная и нужная статья. Спасибо, добавил в избранное.

Но вот оформление кода это что-то… Растащите цепочку вызовов по разным строкам, пожалуйста
Вечером сделаю, к сожалению с работы не могу править пост, прокси режет траффик.
спасибо, познавательно.
правда, честно говоря, мне даже не приходит в голову, как можно программировать какую-то бизнес-логику, не зная о схеме БД.
Ну в любом случае при бизнес-программировании сначала строится граф сущностей и связей между ними «на бумаге». Просто с EF Code First можно пропустить довольно скучный, медленный и рутинный процесс «набивания структуры БД» и написания классов-оберток над таблицами. Тут достаточно или написать новые классы или с помощью Fluent API отобразить существующие POCO.
Хотя синтаксис Fluent API при всей простоте и понятности для сложных баз данных — это кошмар =)
Ну набивать структуру БД тоже не обязательно — Management Studio позволяет достаточно удобно визуально проектировать структуру, которую потом при помощи того же Entity Framework можно перенести в код.
Вопрос тут в том, что брать за основной источник метаданных — код или базу. В обоих случаях у тебя теоретически одинаковые возможности, но на практике детали отличаются. Ну, типа того что в code-first действительно нету индексов, и их нужно в миграции задавать. Зато если code first, то у тебя полный контроль над тем, что у тебя в классах, когда главная БД — приходится их частично генерировать.

Код, как по мне, конкретно в EF удобнее всего получается с code first и встроенными миграциями. Чисто по совокупности плюсов/минусов
Как не зная? Модель контекста дает полную информацию о схеме базы при генерировании EnityModel.
Пост не панацея при выборе метода подхода к проектированию БД, просто кто работает с Code First, сталкиваются с такими проблемами как индексация. Понятно, что для сложного проекта весьма проблематично использовать CF с таком виде, в каком он сейчас есть.
С производительностью проблем нет (имею в виду EF в целом)? На какую в среднем нагрузку рассчитывается?
p.s.
картинка из русифицированной Managment Studio рвёт глаза.
Про производительность? Хм… вопрос интересный, проверка индексов происходит один раз за запуск приложения, так же как и сверяется модель, поэтому здесь Вы разницу вряд ли заметите, построение самих индексов происходит один раз (потребностей в миграция пока не возникает).
Так же, все упирается в скорость работы ORM, меня для маленьких проектов Entity Framework вполне устраивает (~1-2 млн записей в самой большой таблице), на хорошем хостинге отрабатывает моментально (естественно с постраничным выводом и прочими «облегчающими» обстоятельствами).
Про картинку согласен, к сожалению под рукой только русская Managment Studio и русская студия (писал не дома, а на работе куплены именно русские версии)
Ну, по производительности от любой ORM есть прямой и коственный ущерб.

Прямой ущерб — это затраты на сам мэппинг, затраты на мэппинг LINQ в SQL, всякие принципиальные ограничения API. Тут в EF все более-менее нормально: сам по себе он много не жрет, есть способы подоптимизировать, есть способы обойти всякие ограничения.

Коственный ущерб — это что получается в среднем проекте на практике, из-за того что выбрана ORM-парадигма.

На практике с ORM получаются весьма крипожопые запросы, тут и там вылезает всякий lazy loading, тащащий по одному полю за 200 запросов, и т.п. Весьма типично увидеть в профайлере 500 запросов на страничку, и потратить прилично времени чтобы скостить хотя-бы до 50-ти.

Даже от прямого, по меркам ORM, кода, у многих базистов будет батхерт: то, что можно вытащить одной хранимкой в несколько resultset-ов, в ORM весьма типично выдирать в 5-10 SQL-запросов, с дикими join-ами и протаскиванием массивов id-шников с предыдущих запросов.

Впрочем, для очень многих проектов, плюсы ORM перевешивают минусы, а узкие места всегда можно переделать на те же хранимки и руками написанные запросы.
Все перечисленные вами минусы убиваются одним действием — пишете хранимую процедуру и вызываете ее из ORM
Если использовать миграции, то там есть хелпер-метод AddIndex. Ну или просто голым SQL можно все сделать как угодно.

А как жить без миграций (а точнее — с автоматическими миграциями), я не очень понимаю. Только если в самом начале проекта, когда еще нет данных на проде и всяких тестовых/staging-базах, и базу можно пересоздавать на каждый чих. И то — я бы не стал бы.
Интересно другое — если это Code First, то скорее всего классы модели используются в BL. И зачем тогда BL эти знания? Зачем все это на модели?

Кроме того, это привязывает код к подробностям реализации SQL, что IMHO не правильно.

Такому коду (настройки БД и прочее) самое место в одной из реализаций IDatabaseInitializer или подобном.

Согласен с Вами, это удобно на одном двух проектах, но когда они небольшие и их десять-двадцать и не нужно инициализировать базу данных, то гораздо проще добавить пару атрибутов и унаследоваться. Плюс на первостепенном этапе часто бывает, что какие-то сущности уходят, какие то добавляются, лично мне так удобнее, возможно еще кому то по нраву сделать так же, правильнее безусловно сделать как написали Вы.
Небольшое замечание — БД инициализировать нужно всегда, ведь кто-то её должен создавать. Просто по умолчанию используется реализация CreateDatabaseIfNotExists. Но есть и другие варианты (DropCreateDatabaseAlways, DropCreateDatabaseIfModelChanges, MigrateDatabaseToLatestVersion). Более того, унаследовавшись от одного них и переопределив метод Seed() вы можете заполнять БД исходными данными при её создании (например забивать в неё словари и т.п.) А это и в мелких проектах бывает полезно.
IMHO, если нужен полнотекстовый поиск смотрите в сторону ElasticSearch и других подобных решений.

После перевода полнотекстового поиска на ElasticSearch вспоминаю о MS SQL как об ужасном сне.
Возможно так, не пробовал, обязательно возьму на заметку. Сложность заключается в том, что небольшие проекты — это как правило сайты, которые выставляются на «стандартный» хостинг, на который очень и очень сложно добавить что-то свое (я имею ввиду установку ElasticSearch и других подобных решений), а MSSQL со всеми его расширениями предоставляет 95% провайдеров. Опять же статья не призывает использовать такой метод, я лишь описал его, так как меня он полностью устраивает и возможно найдутся другие разработчики, которым это будет удобно.
> В Code First принято все настраивать атрибутами

Я с вами тут не соглашусь. Я всегда предпочитал использовать Fluent API, так как сущность сама по себе не должна предоставлять никакой информации о своих индексах, primary key и т.п. Для этого должен существовать отдельный слой работы с данными.

А так статья хорошая, спасибо.
Да, есть и такой вариант, мне он показался слишком «заковыристым» что-ли, спасибо!
Вот эта строка выдаёт ошибку (невозможно преобразовать типы):
var columnName = ((MemberExpression)((BinaryExpression)func.Body).Left).Member.Name;
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации