Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EF Core 6.0 regression when using HasDefaultSchema() with ToTable(null) #26651

Closed
JustArchi opened this issue Nov 12, 2021 · 4 comments
Closed
Labels
area-migrations closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported regression Servicing-approved type-bug
Milestone

Comments

@JustArchi
Copy link

JustArchi commented Nov 12, 2021

Hey, I'm in the middle of upgrading my application from EF Core 5.0 to EF Core 6.0. I've observed a regression that to the best of my knowledge looks like a bug in EF Core 6.0.

In EF Core 5.0 I have a context with following model creation:

protected override void OnModelCreating(ModelBuilder modelBuilder) {
	modelBuilder.HasDefaultSchema("example");

	// (...) - other parts cut for visibility

	modelBuilder.Entity<VolatilityAgregation>().ToTable(null);
}

ToTable(null) became ambiguous in EF Core 6.0, so I fixed it according to the docs:

protected override void OnModelCreating(ModelBuilder modelBuilder) {
	modelBuilder.HasDefaultSchema("example");

	// (...) - other parts cut for visibility

	modelBuilder.Entity<VolatilityAgregation>().ToTable((string?) null);
}

As a side note, I had to fix all of my past migrations and the model snapshot itself from b.ToTable(null); to b.ToTable((string) null);, this is alright. Everything seems fine after those fixes, code compiles, no errors for now.

The problem however happens when running dotnet ef tool in order to e.g. generate new migration, which refreshes the context snapshot model. It changes my previously-fixed this line:

b.ToTable((string) null);

Into this:

b.ToTable((string)null, "example");

This in result causes an exception when generating a migration script:

System.ArgumentNullException: Value cannot be null. (Parameter 'name')
   at Microsoft.EntityFrameworkCore.Utilities.Check.NotNull[T](T value, String parameterName)
   at Microsoft.EntityFrameworkCore.RelationalEntityTypeBuilderExtensions.ToTable(EntityTypeBuilder entityTypeBuilder, String name, String schema)
   at MyProjectName.Migrations.MyContextModelSnapshot.<>c.<BuildModel>b__0_14(EntityTypeBuilder b) in /data/archi/git/MyCompany/MyProjectName/MyProjectName/Migrations/MyContextModelSnapshot.cs:line 553
   at Microsoft.EntityFrameworkCore.ModelBuilder.Entity(String name, Action`1 buildAction)
   at MyProjectName.Migrations.MyContextModelSnapshot.BuildModel(ModelBuilder modelBuilder) in /data/archi/git/MyCompany/MyProjectName/MyProjectName/Migrations/MyContextModelSnapshot.cs:line 537
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSnapshot.CreateModel()
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSnapshot.get_Model()
   at Microsoft.EntityFrameworkCore.Migrations.Design.MigrationsScaffolder.ScaffoldMigration(String migrationName, String rootNamespace, String subNamespace, String language)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType, String namespace)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType, String namespace)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)

This is because it no longer executes this function:

        public static EntityTypeBuilder ToTable(
            this EntityTypeBuilder entityTypeBuilder,
            string? name)

But this one:

        public static EntityTypeBuilder ToTable(
            this EntityTypeBuilder entityTypeBuilder,
            string name,
            string? schema)

Where name is marked as non-null, and in fact, checked in a safeguard when calling the function.

If you asked me about this, the model -> snapshot generation code should not include default schema name when name is null, generating b.ToTable(null); like before, now corrected to b.ToTable((string)null);. Alternatively, you should allow the string name, string? schema declaration to allow string? name and not throw on it being null, which is a valid use case when the user doesn't want any table generated for given entity. I believe the first option is more appropriate, but I'm not an expert in EF internals so do whatever you consider best, that's only my thoughts in regards to this issue.

As a workaround, I've removed modelBuilder.HasDefaultSchema("example"); which changed b.ToTable((string)null, "example"); into b.ToTable((string)null);, fixing my problem. Obviously this is not the correct solution, as I'd want to have given schema name by default. I didn't find any way to somehow rewrite my ToTable call in OnModelCreating() to solve this issue, no signature allows me to emit no table and skip the default schema name being used in a model, I've tried several - let me know if I missed anything.

Thank you in advance for taking your time to look into this bug report. Let me know if by any chance you need more information and I'll try to provide as much as needed to tackle this one down.

.NET SDK (reflecting any global.json):
 Version:   6.0.100
 Commit:    9e8b04bbff

Runtime Environment:
 OS Name:     debian
 OS Version:  
 OS Platform: Linux
 RID:         debian-x64
 Base Path:   /usr/share/dotnet/sdk/6.0.100/

Host (useful for support):
  Version: 6.0.0
  Commit:  4822e3c3aa

.NET SDKs installed:
  6.0.100 [/usr/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.0 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.0 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

To install additional .NET runtimes or SDKs:
  https://aka.ms/dotnet-download
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.0" />
@ajcvickers
Copy link
Contributor

FYI for those impacted by this issue: EF Core 6.0.1 is now available from NuGet.

@psp-glt
Copy link

psp-glt commented Jun 21, 2023

Still happens in EF Core 7.0.1.0.
have some tables in schema "X"
have some views in schema "Y"
try to configure:

            modelBuilder.HasDefaultSchema("X");
            modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly()); // views of Y configured via Configuration, with schema name specified as builder.ToView("some_Y_view", "Y");
            // configure entities of X without specifying schema X

as result of this, views of schema "Y" in snapshot are configured as:

             b.ToTable(null, "X"); // cause to ArgumentNullException:
             b.ToView("some_Y_view", "Y");

@ajcvickers
Copy link
Contributor

@psp-glt Please open a new issue and attach a small, runnable project or post a small, runnable code listing that reproduces what you are seeing so that we can investigate.

@kurtdowswell-bam
Copy link

We are getting this issue, as described by @psp-glt , as well in v8.0.0

         b.ToTable(null, "X"); // cause to ArgumentNullException:
         b.ToView("some_Y_view", "Y");

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-migrations closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported regression Servicing-approved type-bug
Projects
None yet
Development

No branches or pull requests

5 participants