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

Migration drops non-existent column for model with owned base class but non-owned inherited class #34161

Open
kbaley opened this issue Jul 4, 2024 · 0 comments

Comments

@kbaley
Copy link

kbaley commented Jul 4, 2024

File a bug

Possibly related to: #9630

I have a base class that is owned by another class. I also have a derived class that is part of an unowned relationship. I can generate a migration for this but when I immediately generate a second migration, EF generates one where it wants to delete a column "Discriminator" on the unowned relationship and this column doesn't exist.

This worked in EF Core 6. I ran into this after migrating to EF Core 8. I'm hoping it's an issue with my configuration. I also tested on SQLite and while it still generates similar migrations, dotnet ef database update does work on it.

Include your code

Here's the full reproduction with details in the readme: https://github.com/kbaley/efcore-8-owned-relationship

This is the main part of the code:

using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore;

public class BloggingContext : DbContext
{
    public DbSet<Post> Posts { get; set; }
    public DbSet<Person> People { get; set; }

    public string DbPath { get; }

    public BloggingContext()
    {
        var folder = Environment.SpecialFolder.LocalApplicationData;
        var path = Environment.GetFolderPath(folder);
        DbPath = Path.Join(path, "blogging.db");
    }

    protected override void OnConfiguring(DbContextOptionsBuilder options) {
        var conn = "CONNSTRING";
        options.UseSqlServer(conn);
        // options.UseSqlite();
    }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Post>()
            .OwnsOne(p => p.Address);
    }

}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public Address Address { get; set; }
}

public class Person
{
    public int PersonId { get; set; }
    public IEnumerable<PersonAddress> Addresses { get; set; } = new List<PersonAddress>();
}

public class Address
{
    [Key]
    public int AddressId { get; set; }
    
    public string City { get; set; }
}

public class PersonAddress : Address
{
    public string Street { get; set; }
}

Include stack traces

No stack trace. The error occurs when you try to run dotnet ef database update after generating the second migration.

Include verbose output

Output when running dotnet ef database update --verbose after generating two migrations:

dotnet exec --depsfile /Users/kylebaley/Documents/workspace/efcore-8-owned-relationship/bin/Debug/net8.0/EFGetStarted.deps.json --additionalprobingpath /Users/kylebaley/.nuget/packages --runtimeconfig /Users/kylebaley/Documents/workspace/efcore-8-owned-relationship/bin/Debug/net8.0/EFGetStarted.runtimeconfig.json /Users/kylebaley/.dotnet/tools/.store/dotnet-ef/8.0.6/dotnet-ef/8.0.6/tools/net8.0/any/tools/netcoreapp2.0/any/ef.dll database update --assembly /Users/kylebaley/Documents/workspace/efcore-8-owned-relationship/bin/Debug/net8.0/EFGetStarted.dll --project /Users/kylebaley/Documents/workspace/efcore-8-owned-relationship/EFGetStarted.csproj --startup-assembly /Users/kylebaley/Documents/workspace/efcore-8-owned-relationship/bin/Debug/net8.0/EFGetStarted.dll --startup-project /Users/kylebaley/Documents/workspace/efcore-8-owned-relationship/EFGetStarted.csproj --project-dir /Users/kylebaley/Documents/workspace/efcore-8-owned-relationship/ --root-namespace EFGetStarted --language C# --framework net8.0 --nullable --working-dir /Users/kylebaley/Documents/workspace/efcore-8-owned-relationship --verbose
Using assembly 'EFGetStarted'.
Using startup assembly 'EFGetStarted'.
Using application base '/Users/kylebaley/Documents/workspace/efcore-8-owned-relationship/bin/Debug/net8.0'.
Using working directory '/Users/kylebaley/Documents/workspace/efcore-8-owned-relationship'.
Using root namespace 'EFGetStarted'.
Using project directory '/Users/kylebaley/Documents/workspace/efcore-8-owned-relationship/'.
Remaining arguments: .
Finding DbContext classes...
Finding IDesignTimeDbContextFactory implementations...
Finding application service provider in assembly 'EFGetStarted'...
Finding Microsoft.Extensions.Hosting service provider...
No static method 'CreateHostBuilder(string[])' was found on class 'Program'.
No application service provider was found.
Finding DbContext classes in the project...
Found DbContext 'BloggingContext'.
Using context 'BloggingContext'.
Finding design-time services referenced by assembly 'EFGetStarted'...
Finding design-time services referenced by assembly 'EFGetStarted'...
No referenced design-time services were found.
Finding design-time services for provider 'Microsoft.EntityFrameworkCore.SqlServer'...
Using design-time services from provider 'Microsoft.EntityFrameworkCore.SqlServer'.
Finding IDesignTimeServices implementations in assembly 'EFGetStarted'...
No design-time services were found.
Creating DbConnection.
Created DbConnection. (19ms).
Migrating using database 'Moo' on server 'localhost'.
Opening connection to database 'Moo' on server 'localhost'.
Opened connection to database 'Moo' on server 'localhost'.
Creating DbCommand for 'ExecuteNonQuery'.
Created DbCommand for 'ExecuteNonQuery' (1ms).
Initialized DbCommand for 'ExecuteNonQuery' (2ms).
Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT 1
Executed DbCommand (12ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT 1
Closing connection to database 'Moo' on server 'localhost'.
Closed connection to database 'Moo' on server 'localhost' (1ms).
Creating DbCommand for 'ExecuteScalar'.
Created DbCommand for 'ExecuteScalar' (0ms).
Initialized DbCommand for 'ExecuteScalar' (0ms).
Opening connection to database 'Moo' on server 'localhost'.
Opened connection to database 'Moo' on server 'localhost'.
Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT OBJECT_ID(N'[__EFMigrationsHistory]');
Executed DbCommand (6ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT OBJECT_ID(N'[__EFMigrationsHistory]');
Closing connection to database 'Moo' on server 'localhost'.
Closed connection to database 'Moo' on server 'localhost' (0ms).
Opening connection to database 'Moo' on server 'localhost'.
Opened connection to database 'Moo' on server 'localhost'.
Creating DbCommand for 'ExecuteNonQuery'.
Created DbCommand for 'ExecuteNonQuery' (0ms).
Initialized DbCommand for 'ExecuteNonQuery' (0ms).
Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT 1
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT 1
Closing connection to database 'Moo' on server 'localhost'.
Closed connection to database 'Moo' on server 'localhost' (0ms).
Creating DbCommand for 'ExecuteScalar'.
Created DbCommand for 'ExecuteScalar' (0ms).
Initialized DbCommand for 'ExecuteScalar' (0ms).
Opening connection to database 'Moo' on server 'localhost'.
Opened connection to database 'Moo' on server 'localhost'.
Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT OBJECT_ID(N'[__EFMigrationsHistory]');
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT OBJECT_ID(N'[__EFMigrationsHistory]');
Closing connection to database 'Moo' on server 'localhost'.
Closed connection to database 'Moo' on server 'localhost' (0ms).
Opening connection to database 'Moo' on server 'localhost'.
Opened connection to database 'Moo' on server 'localhost'.
Creating DbCommand for 'ExecuteReader'.
Created DbCommand for 'ExecuteReader' (0ms).
Initialized DbCommand for 'ExecuteReader' (0ms).
Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [MigrationId], [ProductVersion]
FROM [__EFMigrationsHistory]
ORDER BY [MigrationId];
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [MigrationId], [ProductVersion]
FROM [__EFMigrationsHistory]
ORDER BY [MigrationId];
Closing data reader to 'Moo' on server 'localhost'.
A data reader for 'Moo' on server 'localhost' is being disposed after spending 0ms reading results.
Closing connection to database 'Moo' on server 'localhost'.
Closed connection to database 'Moo' on server 'localhost' (0ms).
Applying migration '20240704135003_Moo2'.
Opening connection to database 'Moo' on server 'localhost'.
Opened connection to database 'Moo' on server 'localhost'.
Beginning transaction with isolation level 'Unspecified'.
Began transaction with isolation level 'ReadCommitted'.
Creating DbCommand for 'ExecuteNonQuery'.
Created DbCommand for 'ExecuteNonQuery' (0ms).
Initialized DbCommand for 'ExecuteNonQuery' (0ms).
Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
DECLARE @var0 sysname;
SELECT @var0 = [d].[name]
FROM [sys].[default_constraints] [d]
INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id]
WHERE ([d].[parent_object_id] = OBJECT_ID(N'[PersonAddress]') AND [c].[name] = N'Discriminator');
IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [PersonAddress] DROP CONSTRAINT [' + @var0 + '];');
ALTER TABLE [PersonAddress] DROP COLUMN [Discriminator];
Failed executing DbCommand (7ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
DECLARE @var0 sysname;
SELECT @var0 = [d].[name]
FROM [sys].[default_constraints] [d]
INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id]
WHERE ([d].[parent_object_id] = OBJECT_ID(N'[PersonAddress]') AND [c].[name] = N'Discriminator');
IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [PersonAddress] DROP CONSTRAINT [' + @var0 + '];');
ALTER TABLE [PersonAddress] DROP COLUMN [Discriminator];
Disposing transaction.
Closing connection to database 'Moo' on server 'localhost'.
Closed connection to database 'Moo' on server 'localhost' (0ms).
'BloggingContext' disposed.
Disposing connection to database 'Moo' on server 'localhost'.
Disposed connection to database '' on server '' (0ms).
Microsoft.Data.SqlClient.SqlException (0x80131904): ALTER TABLE DROP COLUMN failed because column 'Discriminator' does not exist in table 'PersonAddress'.
   at Microsoft.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at Microsoft.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at Microsoft.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean isAsync, Int32 timeout, Boolean asyncWrite)
   at Microsoft.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry, String methodName)
   at Microsoft.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQuery(RelationalCommandParameterObject parameterObject)
   at Microsoft.EntityFrameworkCore.Migrations.MigrationCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
   at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQuery(IEnumerable`1 migrationCommands, IRelationalConnection connection)
   at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String connectionString, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(String targetMigration, String connectionString, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
ClientConnectionId:d1ff61f6-5693-403f-a69e-b565705b6c21
Error Number:4924,State:1,Class:16
ALTER TABLE DROP COLUMN failed because column 'Discriminator' does not exist in table 'PersonAddress'.

Include provider and version information

EF Core version: 8.0.6
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 8.0
Operating system: MacOS
IDE: Visual Studio Code / Rider 2023.3.6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants