Använda ett separat migrationsprojekt

Du kan lagra migreringar i ett annat projekt än det som innehåller din DbContext. Detta rekommenderas när programprojektet är plattformsspecifikt, till exempel WinUI, .NET MAUI, Blazor WebAssembly eller Azure Functions, eller när det riktar sig mot en specifik körningsidentifierare (RID). Det kan också användas för att underhålla mer än en uppsättning migreringar.

Tip

Du kan visa den här artikelns sampling på GitHub.

Projektlayout

Exemplet använder tre projekt:

Projekt Ansvar Referenser
WebApplication1.Data Äger entitetstyperna DbContext och EF Core-provider
WebApplication1.Migrations Äger migreringar, modellögonblicksbilden och skapande av designtidskontext Dataprojekt, EF Core-provider och Microsoft.EntityFrameworkCore.Design
WebApplication1 Kör programmet Dataprojekt och migreringsprojekt

Programmet behöver en referens till migreringsprojektet när det identifierar eller tillämpar migreringar vid körning, till exempel genom att anropa Migrate. Om migreringar endast tillämpas av en distributionsartefakt och programmet aldrig läser in dem krävs inte den referensen.

Konfigurera projekten

  1. Skapa ett klassbibliotek för migreringarna och lägg till en referens till projektet som innehåller DbContext.

  2. Lägg till databasprovidern och Microsoft.EntityFrameworkCore.Design till migreringsprojektet. Markera designpaketet som ett beroende för privat utveckling:

    <ItemGroup>
      <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="...">
        <PrivateAssets>all</PrivateAssets>
        <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      </PackageReference>
      <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="..." />
    </ItemGroup>
    
    <ItemGroup>
      <ProjectReference Include="..\WebApplication1.Data\WebApplication1.Data.csproj" />
    </ItemGroup>
    
  3. Implementera IDesignTimeDbContextFactory<TContext> i migreringsprojektet. Med fabriken kan verktygen skapa kontexten utan att köra programprojektet:

    public class ApplicationDbContextFactory : IDesignTimeDbContextFactory<ApplicationDbContext>
    {
        public ApplicationDbContext CreateDbContext(string[] args)
        {
            var connectionString = args.FirstOrDefault()
                ?? @"Server=(localdb)\mssqllocaldb;Database=WebApplication1;Trusted_Connection=True";
    
            var options = new DbContextOptionsBuilder<ApplicationDbContext>()
                .UseSqlServer(
                    connectionString,
                    sqlServer => sqlServer.MigrationsAssembly(typeof(ApplicationDbContextFactory).Assembly.GetName().Name))
                .Options;
    
            return new ApplicationDbContext(options);
        }
    }
    

    Se till att designtidsprovidern och modellkonfigurationen är konsekventa med körningskonfigurationen. Exemplet accepterar ett valfritt reťazec pripojenia argument och använder en lokal utvecklingsanslutning när inget argument anges.

  4. Konfigurera migreringssammansättningen när kontexten registreras vid körning:

    services.AddDbContext<ApplicationDbContext>(
        options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection"),
                x => x.MigrationsAssembly("WebApplication1.Migrations")));
    
  5. Om programmet tillämpar migreringar eller på annat sätt identifierar dem vid körning lägger du till en normal referens från programmet till migreringsprojektet:

    <ItemGroup>
      <ProjectReference Include="..\WebApplication1.Migrations\WebApplication1.Migrations.csproj" />
    </ItemGroup>
    

    Dataprojektet får inte referera till migreringsprojektet. Det skulle skapa ett cirkulärt beroende eftersom migreringsprojektet redan refererar till dataprojektet.

  6. Om det redan finns migreringar flyttar du alla migreringsfiler och modellögonblicksbilden till migreringsprojektet och uppdaterar deras namnområden. När det inte finns några befintliga migreringar tillåter design-time-fabriken att den första migreringen skapas direkt i migreringsprojektet.

Använda verktygen

Använd migreringsprojektet som både målprojekt och startprojekt. Målprojektet tar emot genererade filer medan startprojektet skapas och körs av verktygen. I den här layouten förhindrar användning av migreringsprojektet för båda verktygen att köra programstartkoden.

Kör följande kommandon från lösningskatalogen:

dotnet ef migrations add NewMigration \
    --project WebApplication1.Migrations \
    --startup-project WebApplication1.Migrations

Samma projektalternativ gäller för andra kommandon:

dotnet ef migrations list \
    --project WebApplication1.Migrations \
    --startup-project WebApplication1.Migrations

dotnet ef migrations script --output artifacts/migrations.sql \
    --project WebApplication1.Migrations \
    --startup-project WebApplication1.Migrations

dotnet ef migrations bundle --output artifacts/efbundle \
    --project WebApplication1.Migrations \
    --startup-project WebApplication1.Migrations

Från och med EF Core 11 kan upprepade projektalternativ lagras i .config/dotnet-ef.json.

Skapa migreringsprojektet innan du kör kommandon med --no-build, eller innan en annan process förbrukar utdata. Ett normalt dotnet ef kommando skapar mål- och startprojekten automatiskt.

Plattformsspecifika program

Använd inte ett plattformsspecifikt programprojekt som startprojekt för EF-verktyg. Mobil-, webbläsar-, skrivbords-, funktions- och RID-specifika projekt kan kräva en arbetsbelastning eller intern värd som dotnet ef inte kan köras. Från och med EF Core 11 varnar verktygen när ett plattformsspecifikt startprojekt används.

Använd layouten som beskrivs ovan för .NET MAUI, WinUI, Blazor WebAssembly, Azure Functions och liknande program:

  1. Placera kontext- och entitetstyperna i ett delat dataprojekt.
  2. Placera migreringar och IDesignTimeDbContextFactory<TContext> i ett normalt plattformsoberoende .NET projekt.
  3. Kör verktygen med migreringsprojektet som mål- och startprojekt.
  4. Referera bara till migreringsprojektet från programmet om programmet läser in eller tillämpar migreringar vid körning.

Direkt verktygsstöd för Xamarin- och MAUI-plattformsprojekt är inte planerat. Mer information finns i dotnet/efcore#7152. Xamarin program bör först uppgraderas till .NET MAUI.

Processarkitektur

Processen som kör verktygen måste kunna läsa in varje designtidssammansättning. En 64-bitars Visual Studio eller .NET process kan inte läsa in en x86-endast startsammansättning, och samma villkor gäller för Arm64 och andra arkitekturer. Föredrar ett AnyCPU-migreringsprojekt. Om designtidsberoenden kräver en specifik arkitektur anropar du uttryckligen en matchande .NET SDK.

Arkitekturen för designtidsprocessen är separat från distributionsmålet. När du skapar ett paket använder --target-runtime eller -TargetRuntime genererar du en artefakt för distributions-RID, till exempel linux-arm64 eller osx-arm64.