Ядро Entity Framework: Безопасно ли удалять Migration.Designer.cs, если мы никогда не вернем миграцию?

У нас есть схема базы данных с ~200 таблицами. Снимок модели (Migration.Designer.cs), который создается для каждой миграции, составляет ~ 20 тыс. Строк. Таким образом, наличие большого количества миграций действительно замедляет нашу сборку на CI (при ~30 миграциях создание решения занимает 6 минут с миграциями или 4 минуты без них).

Итак, на вопрос: безопасно ли удалять снимки моделей для старых миграций (которые, как мы знаем, никогда не вернутся)? Используются ли снимки модели для чего-либо еще, кроме Revert-Migration?

5 ответов

Решение

Используются ли снимки модели для чего-либо еще, кроме Revert-Migration?

Да. Есть несколько крайних случаев, когда это необходимо. На SQL Server такие случаи:

  • AlterColumn, когда столбец сужен или вычисленное выражение изменено, и индексы необходимо перестроить
  • CreateIndex для таблицы, оптимизированной для памяти, когда индекс уникален и ссылается на обнуляемые столбцы

Таким образом, большую часть времени, вероятно, безопасно удалить, но, пожалуйста, проверьте, что ваши миграции все еще работают после этого.

У меня такая же проблема с моим текущим проектом. Более 400 переходов и 6 млн строк кода внутри.Designer. Вот как мне удалось решить эту проблему:

MigrationProject.csproj

  <PropertyGroup>
     ...
     <DefaultItemExcludes Condition="'$(Configuration)' == 'Debug' ">$(DefaultItemExcludes);Migrations\**\*.Designer.cs</DefaultItemExcludes>
  </PropertyGroup>

Таким образом, вам не нужно ни сбрасывать миграцию, ни удалять файлы.Designer.

Изменить: это временное решение, вам нужно будет однажды сбросить свои миграции.

Это усовершенствованный подход Хайме Юла.

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

<PropertyGroup Condition="'$(Configuration)'=='DEBUG'">
  <CurrentYear>$([System.DateTime]::Now.Year)</CurrentYear>
  <CurrentMonth>$([System.DateTime]::Now.Month)</CurrentMonth>
  <DefaultItemExcludes>$(DefaultItemExcludes);Migrations\*.Designer.cs</DefaultItemExcludes>
</PropertyGroup>

<ItemGroup>
  <Compile Include="Migrations\$(CurrentYear)$(CurrentMonth)*.Designer.cs" />
</ItemGroup>

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

<PropertyGroup Condition="'$(Configuration)'=='DEBUG'">
  <CurrentMonth>$([System.DateTime]::Now.Month)</CurrentMonth>
  <YearOfCurrentMonth>$([System.DateTime]::Now.Year)</YearOfCurrentMonth>
  <LastMonth>$([System.DateTime]::Now.AddMonths(-1).Month)</LastMonth>
  <YearOfLastMonth>$([System.DateTime]::Now.AddMonths(-1).Year)</YearOfLastMonth>
  <DefaultItemExcludes>$(DefaultItemExcludes);Migrations\*.Designer.cs</DefaultItemExcludes>
</PropertyGroup>

<ItemGroup>
  <Compile Include="Migrations\$(YearOfCurrentMonth)$(CurrentMonth)*.Designer.cs" />
  <Compile Include="Migrations\$(YearOfLastMonth)$(LastMonth)*.Designer.cs" />
</ItemGroup>

И последнее, но не менее важное: мы решили опустить '$(Configuration)'=='DEBUG'condition, поскольку мы только продвигаемся вперед в производстве, а для разработки мы используем EnsureCreated. Поэтому нет необходимости хранить историю всех миграций.

Файл .Designer.cs содержит разделяемый класс с двумя атрибутами:

      [DbContext...
[Migration...

Не забудьте скопировать эти атрибуты в класс, содержащий ваш код миграции (методы Up и Down того же частичного класса).EF использует эти атрибуты, чтобы определить, какие миграции находятся в сборке.

После удаления файлов .Designer.cs из нашего проекта dbContext.Database.GetPendingMigrations().Count() вернул 0.

Мы решили эту проблему, добавив эти атрибуты.

Основываясь на ответах Хайме Юла , Деяна и Бриселама , я создал задачу MSBuild, которая пытается решить эту проблему автоматически. Все, что вам нужно сделать, это установить задачу.

Он автоматически перемещает эти атрибуты из файла в основной файл кода:

      [DbContext...
[Migration...

Он устанавливает*.Designer.csфайлы, которые не нужно компилировать:<DefaultItemExcludes>$(DefaultItemExcludes);**\*.Designer.cs</DefaultItemExcludes>

Затем он ищет последниеN(настраиваемое количество) файлов *.Designer.cs и позволяет компилировать их с помощью<Compile Include="xxx" />

Установить:dotnet add package MSBuild.EntityFrameworkCore.RemoveDesignerCompilation --prerelease

(Вы должны использовать--prereleaseпока не будет опубликована стабильная версия. Сначала мне хотелось бы собрать отзывы о предварительном выпуске)

NuGet

GitHub

Другие вопросы по тегам