Comments 24
Очень полезная и нужная статья. Спасибо, добавил в избранное.
Но вот оформление кода это что-то… Растащите цепочку вызовов по разным строкам, пожалуйста
Но вот оформление кода это что-то… Растащите цепочку вызовов по разным строкам, пожалуйста
спасибо, познавательно.
правда, честно говоря, мне даже не приходит в голову, как можно программировать какую-то бизнес-логику, не зная о схеме БД.
правда, честно говоря, мне даже не приходит в голову, как можно программировать какую-то бизнес-логику, не зная о схеме БД.
Ну в любом случае при бизнес-программировании сначала строится граф сущностей и связей между ними «на бумаге». Просто с EF Code First можно пропустить довольно скучный, медленный и рутинный процесс «набивания структуры БД» и написания классов-оберток над таблицами. Тут достаточно или написать новые классы или с помощью Fluent API отобразить существующие POCO.
Хотя синтаксис Fluent API при всей простоте и понятности для сложных баз данных — это кошмар =)
Хотя синтаксис Fluent API при всей простоте и понятности для сложных баз данных — это кошмар =)
Ну набивать структуру БД тоже не обязательно — Management Studio позволяет достаточно удобно визуально проектировать структуру, которую потом при помощи того же Entity Framework можно перенести в код.
Вопрос тут в том, что брать за основной источник метаданных — код или базу. В обоих случаях у тебя теоретически одинаковые возможности, но на практике детали отличаются. Ну, типа того что в code-first действительно нету индексов, и их нужно в миграции задавать. Зато если code first, то у тебя полный контроль над тем, что у тебя в классах, когда главная БД — приходится их частично генерировать.
Код, как по мне, конкретно в EF удобнее всего получается с code first и встроенными миграциями. Чисто по совокупности плюсов/минусов
Код, как по мне, конкретно в EF удобнее всего получается с code first и встроенными миграциями. Чисто по совокупности плюсов/минусов
Как не зная? Модель контекста дает полную информацию о схеме базы при генерировании EnityModel.
Пост не панацея при выборе метода подхода к проектированию БД, просто кто работает с Code First, сталкиваются с такими проблемами как индексация. Понятно, что для сложного проекта весьма проблематично использовать CF с таком виде, в каком он сейчас есть.
С производительностью проблем нет (имею в виду EF в целом)? На какую в среднем нагрузку рассчитывается?
p.s.
картинка из русифицированной Managment Studio рвёт глаза.
p.s.
картинка из русифицированной Managment Studio рвёт глаза.
Про производительность? Хм… вопрос интересный, проверка индексов происходит один раз за запуск приложения, так же как и сверяется модель, поэтому здесь Вы разницу вряд ли заметите, построение самих индексов происходит один раз (потребностей в миграция пока не возникает).
Так же, все упирается в скорость работы ORM, меня для маленьких проектов Entity Framework вполне устраивает (~1-2 млн записей в самой большой таблице), на хорошем хостинге отрабатывает моментально (естественно с постраничным выводом и прочими «облегчающими» обстоятельствами).
Про картинку согласен, к сожалению под рукой только русская 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 перевешивают минусы, а узкие места всегда можно переделать на те же хранимки и руками написанные запросы.
Прямой ущерб — это затраты на сам мэппинг, затраты на мэппинг LINQ в SQL, всякие принципиальные ограничения API. Тут в EF все более-менее нормально: сам по себе он много не жрет, есть способы подоптимизировать, есть способы обойти всякие ограничения.
Коственный ущерб — это что получается в среднем проекте на практике, из-за того что выбрана ORM-парадигма.
На практике с ORM получаются весьма крипожопые запросы, тут и там вылезает всякий lazy loading, тащащий по одному полю за 200 запросов, и т.п. Весьма типично увидеть в профайлере 500 запросов на страничку, и потратить прилично времени чтобы скостить хотя-бы до 50-ти.
Даже от прямого, по меркам ORM, кода, у многих базистов будет батхерт: то, что можно вытащить одной хранимкой в несколько resultset-ов, в ORM весьма типично выдирать в 5-10 SQL-запросов, с дикими join-ами и протаскиванием массивов id-шников с предыдущих запросов.
Впрочем, для очень многих проектов, плюсы ORM перевешивают минусы, а узкие места всегда можно переделать на те же хранимки и руками написанные запросы.
Если использовать миграции, то там есть хелпер-метод AddIndex. Ну или просто голым SQL можно все сделать как угодно.
А как жить без миграций (а точнее — с автоматическими миграциями), я не очень понимаю. Только если в самом начале проекта, когда еще нет данных на проде и всяких тестовых/staging-базах, и базу можно пересоздавать на каждый чих. И то — я бы не стал бы.
А как жить без миграций (а точнее — с автоматическими миграциями), я не очень понимаю. Только если в самом начале проекта, когда еще нет данных на проде и всяких тестовых/staging-базах, и базу можно пересоздавать на каждый чих. И то — я бы не стал бы.
Интересно другое — если это Code First, то скорее всего классы модели используются в BL. И зачем тогда BL эти знания? Зачем все это на модели?
Кроме того, это привязывает код к подробностям реализации SQL, что IMHO не правильно.
Такому коду (настройки БД и прочее) самое место в одной из реализаций IDatabaseInitializer или подобном.
Кроме того, это привязывает код к подробностям реализации SQL, что IMHO не правильно.
Такому коду (настройки БД и прочее) самое место в одной из реализаций IDatabaseInitializer или подобном.
Согласен с Вами, это удобно на одном двух проектах, но когда они небольшие и их десять-двадцать и не нужно инициализировать базу данных, то гораздо проще добавить пару атрибутов и унаследоваться. Плюс на первостепенном этапе часто бывает, что какие-то сущности уходят, какие то добавляются, лично мне так удобнее, возможно еще кому то по нраву сделать так же, правильнее безусловно сделать как написали Вы.
Небольшое замечание — БД инициализировать нужно всегда, ведь кто-то её должен создавать. Просто по умолчанию используется реализация CreateDatabaseIfNotExists. Но есть и другие варианты (DropCreateDatabaseAlways, DropCreateDatabaseIfModelChanges, MigrateDatabaseToLatestVersion). Более того, унаследовавшись от одного них и переопределив метод Seed() вы можете заполнять БД исходными данными при её создании (например забивать в неё словари и т.п.) А это и в мелких проектах бывает полезно.
IMHO, если нужен полнотекстовый поиск смотрите в сторону ElasticSearch и других подобных решений.
После перевода полнотекстового поиска на ElasticSearch вспоминаю о MS SQL как об ужасном сне.
После перевода полнотекстового поиска на ElasticSearch вспоминаю о MS SQL как об ужасном сне.
Возможно так, не пробовал, обязательно возьму на заметку. Сложность заключается в том, что небольшие проекты — это как правило сайты, которые выставляются на «стандартный» хостинг, на который очень и очень сложно добавить что-то свое (я имею ввиду установку ElasticSearch и других подобных решений), а MSSQL со всеми его расширениями предоставляет 95% провайдеров. Опять же статья не призывает использовать такой метод, я лишь описал его, так как меня он полностью устраивает и возможно найдутся другие разработчики, которым это будет удобно.
> В Code First принято все настраивать атрибутами
Я с вами тут не соглашусь. Я всегда предпочитал использовать Fluent API, так как сущность сама по себе не должна предоставлять никакой информации о своих индексах, primary key и т.п. Для этого должен существовать отдельный слой работы с данными.
А так статья хорошая, спасибо.
Я с вами тут не соглашусь. Я всегда предпочитал использовать Fluent API, так как сущность сама по себе не должна предоставлять никакой информации о своих индексах, primary key и т.п. Для этого должен существовать отдельный слой работы с данными.
А так статья хорошая, спасибо.
Вот эта строка выдаёт ошибку (невозможно преобразовать типы):
var columnName = ((MemberExpression)((BinaryExpression)func.Body).Left).Member.Name;
var columnName = ((MemberExpression)((BinaryExpression)func.Body).Left).Member.Name;
Sign up to leave a comment.
Entity Framework Code First — индексация полей и полнотекстовый поиск