Skip to main content

Fixed: "Model building is not supported when publishing with NativeAOT" with dotnet run and EF Core

· 6 min read
Jagdish Kumawat
Founder @ Dewiride

dotnet run app.cs, on a small program with a DbContext, stopped with Model building is not supported when publishing with NativeAOT. I wasn't publishing anything. File-based apps turn native AOT on by default, and one line at the top of the file turns it off.

What I Was Doing​

I wanted to check that MySqlConnection.ClearPool works on the connection a DbContext holds, so I wrote a one-file C# program. It uses the .NET 10 SDK, EF Core 10.0.14 and Oracle's MySql.EntityFrameworkCore 10.0.12:

app.cs
#:package MySql.EntityFrameworkCore@10.0.12
#:package Microsoft.EntityFrameworkCore.Relational@10.0.14

using Microsoft.EntityFrameworkCore;
using MySql.Data.MySqlClient;
using MySql.EntityFrameworkCore.Extensions;

var connectionString = Environment.GetEnvironmentVariable("MYSQL_CONNECTION_STRING")!;
var options = new DbContextOptionsBuilder<DemoContext>().UseMySQL(connectionString).Options;
await using var db = new DemoContext(options);

async Task<int> OpenAndCloseAsync()
{
await db.Database.OpenConnectionAsync();
var id = ((MySqlConnection)db.Database.GetDbConnection()).ServerThread;
await db.Database.CloseConnectionAsync();
return id;
}

Console.WriteLine($"First open: connection id {await OpenAndCloseAsync()}");
Console.WriteLine($"Second open: connection id {await OpenAndCloseAsync()}");
MySqlConnection.ClearPool((MySqlConnection)db.Database.GetDbConnection());
Console.WriteLine($"After ClearPool: connection id {await OpenAndCloseAsync()}");

sealed class DemoContext(DbContextOptions<DemoContext> options) : DbContext(options);

I ran it the way How to Run a Single C# File with dotnet run describes:

Terminal
dotnet run app.cs

What I Expected​

Three lines, with one connection id printed twice, and then a new one.

What I Got​

Output
/Users/you/projects/ef-demo/app.cs(25,67): warning IL2026: Using member 'Microsoft.EntityFrameworkCore.DbContext.DbContext(DbContextOptions)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. EF Core isn't fully compatible with trimming, and running the application may generate unexpected runtime failures. Some specific coding pattern are usually required to make trimming work properly, see https://aka.ms/efcore-docs-trimming for more details.
/Users/you/projects/ef-demo/app.cs(25,67): warning IL3050: Using member 'Microsoft.EntityFrameworkCore.DbContext.DbContext(DbContextOptions)' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. EF Core isn't fully compatible with NativeAOT, and running the application may generate unexpected runtime failures.
Unhandled exception. System.InvalidOperationException: Model building is not supported when publishing with NativeAOT. Use a compiled model.

dotnet run app.cs printing warnings IL2026 and IL3050 about DbContext, then Unhandled exception. System.InvalidOperationException: Model building is not supported when publishing with NativeAOT.

Two warnings from the build, then an exception on the first line that used the context.

What I Checked​

Whether I was publishing. I wasn't: this was dotnet run. The same provider builds its model without trouble in my API, which is a normal project. So something was different about a one-file program.

What a one-file program turns on. dotnet project convert app.cs writes out the project that a one-file program builds as, and it has this line:

app.csproj
<PublishAot>true</PublishAot>

Microsoft's file-based apps page confirms it: "File-based apps enable native AOT publishing by default, producing optimized, self-contained executables."

What that does when you only run the program. The build's app.runtimeconfig.json, which on my Mac is under ~/Library/Application Support/dotnet/runfile/, has this setting:

app.runtimeconfig.json
"System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported": false

So even under dotnet run, the program behaves as if it can't generate code while it runs.

What the error suggests. It says "Use a compiled model". EF Core's NativeAOT page says: "NativeAOT and query precompilation are highly experimental feature, and are not yet suited for production use." That's a lot of machinery for a small test program, and I didn't need AOT at all.

Why It Happens​

EF Core normally builds its model the first time a context is used, by inspecting your classes as the program runs. Native AOT doesn't allow that. A file-based app has PublishAot on by default, and that also tells the runtime that dynamic code isn't supported, so EF Core refuses before it starts.

The Fix​

Turn it off, on the first line of the file:

app.cs (the first line)
#:property PublishAot=false

The page gives exactly this: "Disable this feature by adding #:property PublishAot=false at the top of your file."

After the Fix​

Terminal
dotnet run app.cs
Output
First open: connection id 4871
Second open: connection id 4871
After ClearPool: connection id 4872

With the property at the top of the file, dotnet run app.cs printing connection id 4871 twice, then 4872 after ClearPool, with no warnings.

The program works, and the two warnings have gone too.

Common Mistakes​

MistakeWhat happensDo this instead
Reading it as a publishing problemYou look in the wrong place, because you aren't publishingCheck for PublishAot
Putting the line below a usingCS9297Put it first
Converting to a project to get away from itdotnet project convert keeps PublishAot, and I got the same errorSet it to false in the .csproj
Ignoring warnings IL2026 and IL3050They told me about this before it failedRead them

Troubleshooting​

SymptomLikely causeFix
Reflection-based serialization has been disabledThe same setting, in System.Text.JsonThe fix
It still fails after adding the lineThe line isn't in the file you're runningCheck the file name in the command
You really do want native AOTEF Core needs a compiled model for thatRead the NativeAOT page, and its warning

Conclusion​

File-based apps turn native AOT on by default, and EF Core can't build its model under it. Add #:property PublishAot=false as the first line of the file.

Additional Resources​

Stay Updated

Subscribe to our newsletter for the latest tutorials, tech insights, and developer news.

By subscribing, you agree to our privacy policy. Unsubscribe at any time.