EF Core 2尝试两次创建相同的表

时间:2017-08-31 09:09:51

标签: entity-framework entity-framework-core

我有一个使用EF Core 2的项目。我创建了一个迁移。运行迁移时,它返回以下错误:

infoinfo:    System.Data.SqlClient.SqlException (0x80131904): There is already an object named 'Clients' in the database.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite)
   at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite, String methodName)
   at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, DbCommandMethod executeMethod, IReadOnlyDictionary`2 parameterValues)
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
   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 contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_1.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
ClientConnectionId:718d9d47-c2e4-4bf5-9e15-165884a5ff11
Error Number:2714,State:6,Class:16
infoerror:   There is already an object named 'Clients' in the database.
: Microsoft.EntityFrameworkCore.Database.Command[200101]
  Executed DbCommand (8ms) [Parameters=[@p0='?' (Size = 400), @p1='?' (Size = 400), @p2='?' (Size = 4000), @p3='?', @p4='?', @p5='?' (Size = 400), @p6='?' (Size = 400), @p7='?' (Size = 4000), @p8='?', @p9='?', @p10='?' (Size = 400), @p11='?' (Size = 400), @p12='?' (Size = 4000), @p13='?', @p14='?', @p15='?' (Size = 400), @p16='?' (Size = 400), @p17='?' (Size = 4000), @p18='?', @p19='?'], CommandType='Text', CommandTimeout='30']
  SET NOCOUNT ON;
  DECLARE @inserted0 TABLE ([Id] int, [_Position] [int]);
  MERGE [Options] USING (
  VALUES (@p0, @p1, @p2, @p3, @p4, 0),
  (@p5, @p6, @p7, @p8, @p9, 1),
  (@p10, @p11, @p12, @p13, @p14, 2),
  (@p15, @p16, @p17, @p18, @p

这是我的DbContext:

namespace MyProject.Data
{
    public class MyProjectContext : DbContext
    {
        public MyProjectContext(DbContextOptions<MyProjectContext> options)
            : base(options)
        {
        }

        public DbSet<ExtensionBasicQuotation> ExtensionBasicQuotations { get; set; }
        public DbSet<ExtensionSpecifiedQuotation> ExtensionSpecifiedQuotations { get; set; }
        public DbSet<Client> Clients { get; set; }
        public DbSet<Option> Options { get; set; }
        public DbSet<SpecifiedQuotationAttachment> SpecifiedQuotationAttachments { get; set; }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            builder.ApplyConfiguration(new ClientConfiguration());
            builder.ApplyConfiguration(new ExtensionBasicQuotationConfiguration());
            builder.ApplyConfiguration(new ExtensionSpecifiedQuotationConfiguration());
            builder.ApplyConfiguration(new OptionConfiguration());
        }
    }
}

只有一个迁移,迁移只有一个用于Clients表的CreateTable函数。

migrationBuilder.CreateTable(
                name: "Clients",
                columns: table => new
                {
                    Id = table.Column<int>(type: "int", nullable: false)
                        .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                    Address = table.Column<string>(type: "nvarchar(500)", maxLength: 500, nullable: true),
                    City = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: true),
                    Email = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: true),
                    Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: true),
                    Phone = table.Column<string>(type: "nvarchar(20)", maxLength: 20, nullable: true),
                    Postcode = table.Column<string>(type: "nvarchar(20)", maxLength: 20, nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Clients", x => x.Id);
                });

为什么Clients表创建了两次?

3 个答案:

答案 0 :(得分:3)

我发现EF Core 2.0存在同样的问题

创建Seeder类时,问题出现在种子方法中:

_ctx.Database.EnsureCreated();

然后,如果您添加迁移(Initial或一个包含更多表)并执行数据库更新,播种机将首先尝试创建数据库(但不知道历史记录中的版本记录?)然后更新将尝试试。

无论如何,在种子方法中注释掉前一行修复了问题。

答案 1 :(得分:2)

如果此迁移是InitialCreate迁移,那么如果您已经拥有数据库,则似乎不应该运行它,它应该仅用于创建新数据库。

  

如果在数据库已存在时创建了初始迁移,   生成数据库创建代码但不必运行   因为数据库已经匹配数据模型。部署时   应用程序到数据库尚不存在的另一个环境,   此代码将运行以创建您的数据库

http://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/migrations

答案 2 :(得分:0)

我遇到了类似的问题,数据库是根据初始迁移创建的,但是迁移表是空的。 所以修复是手动填充它:

  • MigrationName 位于 _migrationName_.Designer.cs 文件内的属性中,例如[Migration("20210209115216_InitialMigration")]
  • ProductVersion 位于上下文的快照类中,例如MyDbContextModelSnapshot,有一行.HasAnnotation("ProductVersion", "5.0.2");

我在使用初始迁移脚本时遇到了这种延迟,但我认为对于任何具有类似修复程序的迁移,它都可以重现。