Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Varning
NativeAOT och frågeförkompilering är mycket experimentella funktioner och passar ännu inte för produktionsanvändning. Det stöd som beskrivs nedan bör ses som infrastruktur mot den slutliga funktionen, som kommer att släppas i en framtida version. Vi rekommenderar att du experimenterar med det aktuella stödet och rapporterar om dina upplevelser, men rekommenderar att du inte distribuerar EF NativeAOT-program i produktion. Se nedan för specifika kända begränsningar.
.NET NativeAOT tillåter publicering av fristående .NET-program som har kompilerats i förväg (AOT). Om du gör det får du följande fördelar:
- Betydligt snabbare starttid för program
- Små fristående binärfiler som har mindre minnesfotavtryck och som är enklare att distribuera
- Köra program i miljöer där just-in-time-kompilering inte stöds
EF-program som publicerats med NativeAOT startar mycket snabbare än samma program utan det. Förutom de allmänna .NET-startförbättringar som NativeAOT erbjuder (dvs. ingen JIT-kompilering krävs varje gång), förkompileras ÄVEN LINQ-frågor när du publicerar ditt program, så att ingen bearbetning behövs när du startar och SQL redan är tillgängligt för omedelbar körning. Ju fler EF LINQ-frågor ett program har i sin kod, desto snabbare förväntas startvinsterna vara.
Publicera ett EF NativeAOT-program
Aktivera först NativeAOT-publicering för projektet på följande sätt:
<PropertyGroup>
<PublishAot>true</PublishAot>
</PropertyGroup>
EF:s stöd för LINQ-frågekörning under NativeAOT bygger på frågeförkompilering: den här mekanismen identifierar STATISKA EF LINQ-frågor och genererar C#- interceptorer som innehåller kod för att köra varje specifik fråga. Detta kan avsevärt minska programmets starttid, eftersom det tunga arbetet med bearbetning och kompilering av LINQ-frågor till SQL inte längre sker varje gång programmet startas. I stället innehåller varje frågas interceptor den färdiga SQL-filen för den frågan, samt optimerad kod för att materialisera databasresultat som .NET-objekt.
C#-interceptorer är för närvarande en experimentell funktion och kräver en särskild anmälning i projektfilen:
<PropertyGroup>
<InterceptorsNamespaces>$(InterceptorsNamespaces);Microsoft.EntityFrameworkCore.GeneratedInterceptors</InterceptorsNamespaces>
</PropertyGroup>
Slutligen Microsoft.EntityFrameworkCore.Tasks innehåller paketet MSBuild-integrering som utför frågeförkompileringen (och genererar den nödvändiga kompilerade modellen) när du publicerar programmet:
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tasks" Version="9.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
Nu är du redo att publicera ditt EF NativeAOT-program:
dotnet publish -r linux-arm64 -c Release
Anmärkning
Publiceringskommandot kan misslyckas med felet CS9137. Orsaken till det här felet är inaktuella transitiva paketreferenser Microsoft.CodeAnalysis.CSharp.Workspaces och Microsoft.CodeAnalysis.Workspaces.MSBuild. Som en lösning lägger du uttryckligen till dessa paket i .csproj-filen:
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.13.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="4.13.0" />
Mer information finns i detta ärende.
Detta visar hur man publicerar en NativeAOT-distribution för Linux som körs på ARM64; rådfråga denna katalog för att hitta ditt runtime-ID. Om du vill generera interceptorerna utan att publicera – till exempel för att undersöka de genererade källorna – kan du göra det via dotnet ef dbcontext optimize --precompile-queries --nativeaot kommandot .
På grund av hur C#-avlyssningsprogram fungerar ogiltigförklarar alla ändringar i programkällan dem och kräver att ovanstående process upprepas. Därför förväntas inte generering av interceptor och faktisk publicering ske i den inre loopen eftersom utvecklaren arbetar med kod. i stället kan både dotnet ef dbcontext optimize och dotnet publish köras i ett arbetsflöde för publicering/distribution i ett CI/CD-system.
Anmärkning
Publicering rapporterar för närvarande ett antal trimnings- och NativeAOT-varningar, vilket innebär att din applikation inte garanterat fungerar korrekt. Detta förväntas med tanke på det aktuella experimentella tillståndet för NativeAOT-stöd. den slutliga, icke-experimentella funktionen rapporterar inga varningar.
Begränsningar
Dynamiska frågor stöds inte
Frågeförkompilering utför statisk analys av källkoden, identifierar EF LINQ-frågor och genererar C#-interceptorer för dem. LINQ gör det möjligt att uttrycka mycket dynamiska frågor, där LINQ-operatorer är sammansatta baserat på godtyckliga villkor. sådana frågor kan tyvärr inte analyseras statiskt och stöds för närvarande inte. Tänk på följande exempel:
IAsyncEnumerable<Blog> GetBlogs(BlogContext context, bool applyFilter)
{
IQueryable<Blog> query = context.Blogs.OrderBy(b => b.Id);
if (applyFilter)
{
query = query.Where(b => b.Name != "foo");
}
return query.AsAsyncEnumerable();
}
Ovanstående fråga delas upp i flera instruktioner och skapar operatorn Where dynamiskt baserat på en extern parameter. Sådana frågor kan inte förkompileras. Ibland går det dock att skriva om sådana dynamiska frågor som flera icke-dynamiska frågor:
IAsyncEnumerable<Blog> GetBlogs(BlogContext context, bool applyFilter)
=> applyFilter
? context.Blogs.OrderBy(b => b.Id).Where(b => b.Name != "foo").AsAsyncEnumerable()
: context.Blogs.OrderBy(b => b.Id).AsAsyncEnumerable();
Eftersom de två frågorna kan analyseras statiskt från början till slut kan förkompileringen hantera dem.
Observera att dynamiska frågor sannolikt kommer att stödjas i framtiden när du använder NativeAOT. Men eftersom de inte kan förkompileras fortsätter de att sakta ned programstarten och presterar i allmänhet mindre effektivt jämfört med icke-NativeAOT-körning. Det beror på att EF internt förlitar sig på kodgenerering för att materialisera databasresultat, men kodgenerering stöds inte när du använder NativeAOT.
Andra begränsningar
- LINQ-frågeuttryckssyntax (kallas ibland "förståelsesyntax") stöds inte.
- Den genererade kompilerade modellen och frågeavlyssnare kan för närvarande vara ganska stora när det gäller kodstorlek och ta lång tid att generera. Vi planerar att förbättra detta.
- EF-leverantörer kan behöva bygga in stöd för förkompilerade frågor. Kontrollera leverantörens dokumentation för att veta om den är kompatibel med EF:s NativeAOT-support.
- Värdekonverterare som använder insamlat tillstånd stöds inte.
Förkompilerade frågor utan NativeAOT
På grund av de aktuella begränsningarna i EF:s NativeAOT-stöd kanske det inte går att använda för vissa program. Du kanske dock kan dra nytta av förkompilerade frågor när du publicerar vanliga, icke-NativeAOT-program. Detta gör att du åtminstone kan dra nytta av den minskning av starttiden som förkompilerade frågor erbjuder, samtidigt som du kan använda dynamiska frågor och andra funktioner som för närvarande inte stöds med NativeAOT.
Att använda förkompilerade frågor utan NativeAOT handlar helt enkelt om att köra följande:
dotnet ef dbcontext optimize --precompile-queries
Som det visas ovan genererar detta en kompilerad modell och interceptorer för frågor som kan förkompileras, vilket tar bort deras belastning från applikationens starttid.