Pull to refresh
6
0
Yurii Zhoholiev @sndr

Пользователь

Send message
Наверное Вы меня не поняли.
EF = Entity Framework.
Статья примитивненькая, т.к. все описанное в ней достаточно очевидно, если уже доводилось решать проблемы с оптимизацией работы EF и там встречаются и более интересные случаи (типа разворачивания Navigation Property в OUTER JOIN вместо INNER JOIN и обход этого явным сравнением значения с null и т.д.).
В работе случалось и не такие запросы оптимизировать, поэтому и привел как рекомендацию утилиту LinqPad, которая позволяет анализировать запросы, в которые EF транслирует выражения.
Ну и если объективно, актуальность этой статьи под вопросом, т.к. сейчас все переходят на .NET Core и больший интерес представляет EF Core 2.2, т.к. поддержку .NET Standard в EF обещают только в 6.3 (и то с ограничениями) и ничего нового в эту ORM вероятнее всего уже добавляться не будет.
Статья, конечно, примитивненькая (если вы работаете с EF).
Общее правило при работе с EF — не уверен в качестве сгенерированного кода — перепроверяй его в LinqPad (https://www.linqpad.net/) и доводи до вменяемого состояния.
Skype, VSCode, Visual Studio Installer, Azure Storage Explorer. Это то, что видел пока.
Судя по тому, что использует сам MS в последнее время — electronjs.org
Такие ролики нужно смотреть только под этот саундтрек www.youtube.com/watch?v=EFLFH8GW4gs

Военная база в Аламеде, ракеты и т.д. Не иначе Хайнаман и Севидж балуются.

Модель чтения никак не связана с моделью корневого агрегата и не требует его материализации. Полное «проигрывание» событий необходимо лишь при изменении или дополнении модели чтения и требуется 1 раз. Остальные изменения в основном реализовываются инкрементально и мутируют модель чтения во время обработки соответсвуюших событий.

Чтобы гарантировать порядок транзакций.

Судя по набору ограничений, для решения данной задачи, достаточно применить венгерский алгоритм.
Возможно применили, что-то другое.

Про год, это я к тому, что уже есть TPL, PLINQ, async/await, различные потокобезопасные структуры данных и т. д., поэтому код, который использует ThreadPool.QueueUserWorkItem напрямую вызывает некоторые вопросы сам собой, не говоря уже о конкретном способе его использования и блокировок.
Я не знаю, какую версию .NET вы используете и что подвигло вас использовать тот или иной подход к релазиации многопоточности в 2016 году но пару моментов бросились в гласа сразу:

lock (PageStore) {
   PageStore[pageNumber] = mem;
}

Зачем использовать Dictionary<int, MemoryStream>, если у Вас используется доступ по индексу, когда есть MemoryStream[] и неблокирующий доступ по индексу, а количество можно определять использую атомарный инкремент?
Ну и еще, т. к. процесс печати так же занимает определенное время стоит посмотреть в сторону блокирующих очередей (BlockingCollection в .NET 4+), Reactive Extensions и Dataflow.
В основном согласен, в плане того, что специфические запросы реализовать в виде методов, а остальное дать на откуп пользователям, которые могут выполнить специфические запросы или целые комбинации запросов. В процессе использования будут кристаллизированны и другие необходимые методы.

Зачем вам тогда репозиторй вообще?

Не стоит забывать о том, что Repository является дополнительным уровнем абстракции, который вы контролируете. Нет привязки к конкретному хранилищу или технологии хранения. Так же, можно вводить дополнительные ограничения, которые диктуются другими используемыми принципами проектирования, например, репозитории могут быть реализованы только для корневых объектов (aggregate root), т.е. появляется дополнительный контроль над выполнением принципов DDD.
Согласен, это возможно в случае наличия Navigation Properties.

Однако, если воспользоваться методом, который описан в коде, то мы полностью возлагаете контроль времени жизни на .NET Framework. Что за частую означает, что контекст не будет освобожден достаточно продолжительный промежуток времени.

Хотел бы отметить, что наличие свойств с отложенной загрузкой вне рамок конкретного репозитория, или какого-то дополнительного уровня (например уровня сервисов), может привести к неожиданному поведению в процессе дальнейшего использования.
Зачастую возникают случаи, когда пользователь ожидает 1 вызов базы данных, в то время, как получает N+1 вызов (например, к этому может привести обращение к свойству навигации, которое является коллекцией каких-то элементов, в цикле foreach).

Общими рекомендациями при работе со свойствами навигации являются следующие:
1. Не использовать отложенную загрузку или перенести ее включение на этап оптимизации.
2. Не использовать свойства навигации выше определенного уровня абстракции (например, уровня репозитория или сервисов). При этом подключать необходимые свойства навигации при помощи методов Explicit loading или Eager loading (при помощи метода Include).
3. Использовать DbContext, время жизни которого есть возможность контролировать (например, использовать для этого IoC контейнер).
Дополнительно:
var dbContext = new AppDbContext();

Упущен контроль времени жизни контекста данных.
Одно из общих правил работы с контекстом данных состоит в том, что контекст необходимо освобождать, как только он перестает быть необходимым.
Т.е. в данном случае необходимо воспользоваться оператором using:

using (var dbContext = new AppDbContext()){
...
}
Совет №3. Массовое обновление данных с помощью DetectChanges

В EF 6 добавлены методы DbSet.AddRange и DbSet.RemoveRange, которые решают данную проблему.

Кстати, иногда для ускорения вставки так же рекомендуют отключить DbContext.Configuration.ValidateOnSaveEnabled, но это может привести к соответствующим результатам, поэтому этим стоит пользоваться, только если проверка данных была предварительно произведена.
В EF 6.1 был добавлен атрибут IndexAttrubute, который делает то, о чем вы просите.

Если вдаться в детали, то это работает через добавление IndexAnnotation через IndexAttributeConvention, т.е. проходим по классу, находим атрибуты IndexAttribute и добавляем в соответствующие свойства необходимые аннотации (кстати, добавление атрибутов через Code First выглядит именно так).

Далее, на базе аннотаций EF определяет получившийся набор изменений и на базе этого набора генерируется код миграции.

Если мы хотим, чтобы генерировался код, для нашей пользовательской миграции, то здесь есть проблема. Она заключается в том, что генерация списка операций, которые необходимо добавить в миграцию происходит в классе System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer, который является внутренним и изменить его нельзя (надеюсь в одном из следующих релизов EF и это изменят).

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

Information

Rating
Does not participate
Location
Киев, Киевская обл., Украина
Date of birth
Registered
Activity