skip to Main Content

I’m new to ASP.NET Core Web API and I don’t know if this is a simple one but:

I’m working on an ASP.NET Core Web API project and I need to add a new table to the database. There are already existing tables in the database as well. However, I’m not seeing any migration folders in the directory of the project application nor is there a MigrationHistory in the database so I think the tables where created in the SSMS itself. I created a new model named SampleNewTable1 and I’ve also added it to the existing DbContext named DataContext.

When I ran Add-Migration NewMigration -Context DataContext, it created a new folder Migrations in the project that included my NewMigration file and a DataContextModelSnapshot.

When I ran Update-Database -Context DataContext

It produces this error:

Microsoft.Data.SqlClient.SqlException (0x80131904): There is already an object named 'SampleExistingTable1' in the database.
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:<ID>
Error Number:2714,State:6,Class:16
There is already an object named 'SampleExistingTable1' in the database.

The NewMigration file contains this block of code:

using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace SampleApp.Migrations
{
    public partial class InitialMigration : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "SampleExistingTable1",
                columns: table => new
                {
                    Id = table.Column<int>(type: "int", nullable: false)
                        .Annotation("SqlServer:Identity", "1, 1"),
                    DataReceived = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    Transfered = table.Column<int>(type: "int", nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_SampleExistingTable1", x => x.Id);
                });

            migrationBuilder.CreateTable(
                name: "SampleExistingTable2",
                columns: table => new
                {
                    Id = table.Column<int>(type: "int", nullable: false)
                        .Annotation("SqlServer:Identity", "1, 1"),
                    DataReceived = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    Transfered = table.Column<int>(type: "int", nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_SampleExistingTable2", x => x.Id);
                });

            migrationBuilder.CreateTable(
                name: "SampleNewTable1",
                columns: table => new
                {
                    Id = table.Column<int>(type: "int", nullable: false)
                        .Annotation("SqlServer:Identity", "1, 1"),
                    DataReceived = table.Column<string>(type: "nvarchar(max)", nullable: true),
                    Transfered = table.Column<int>(type: "int", nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_SampleNewTable1", x => x.Id);
                });
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropTable(
                name: "SampleExistingTable1");

            migrationBuilder.DropTable(
                name: "SampleExistingTable2");

            migrationBuilder.DropTable(
                name: "SampleNewTable1");
        }
    }
}

The Snapshot contains this auto-generated code:

// <auto-generated />
using System;
using SampleApp.Contexts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;

#nullable disable

namespace SampleApp.Migrations
{
    [DbContext(typeof(DataContext))]
    partial class DataContextModelSnapshot : ModelSnapshot
    {
        protected override void BuildModel(ModelBuilder modelBuilder)
        {
#pragma warning disable 612, 618
            modelBuilder
                .HasAnnotation("ProductVersion", "6.0.6")
                .HasAnnotation("Relational:MaxIdentifierLength", 128);

            SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);

            modelBuilder.Entity("SampleApp.Models.SampleNewTable1", b =>
                {
                    b.Property<int>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("int");

                    SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);

                    b.Property<string>("DataReceived")
                        .HasColumnType("nvarchar(max)");

                    b.Property<int?>("Transfered")
                        .HasColumnType("int");

                    b.HasKey("Id");

                    b.ToTable("SampleNewTable1", (string)null);
                });

            modelBuilder.Entity("SampleApp.Models.SampleExistingTable1", b =>
                {
                    b.Property<int>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("int");

                    SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);

                    b.Property<string>("DataReceived")
                        .HasColumnType("nvarchar(max)");

                    b.Property<int?>("Transfered")
                        .HasColumnType("int");

                    b.HasKey("Id");

                    b.ToTable("SampleExistingTable1", (string)null);
                });

            modelBuilder.Entity("SampleApp.Models.SampleExistingTable2", b =>
                {
                    b.Property<int>("Id")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("int");

                    SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);

                    b.Property<string>("DataReceived")
                        .HasColumnType("nvarchar(max)");

                    b.Property<int?>("Transfered")
                        .HasColumnType("int");

                    b.HasKey("Id");

                    b.ToTable("SampleExistingTable2", (string)null);
                });
#pragma warning restore 612, 618
        }
    }
}

How do I add a condition to not simply add or update tables depending if it:

  1. Exists, without new changes to it’s properties. Do Nothing
  2. Exists, with new changes to it’s properties. Update
  3. Does not exist. Add

2

Answers


  1. Is there a reason for adding the tables to the database using EntityFramework versus the same way that all previous tables were created (i.e., SSMS)?

    I’ve used the Migrations in previous projects and they prove quite useful for code-first implementations where the project was new and the schemas were defined by my code, but I’ve learned that often projects that are utilizing existing databases may find it easier to continue their management of tables and schemas through DBAs.

    Could you perhaps provide some additional context as to your required usage of migrations using EntityFramework?

    Login or Signup to reply.
  2. You could check this document related with working with existing database(Notice it was for EF6 not EFCore)

    For EFCore ,you could try as below:
    1,create Entities and Dbcontext accroding to your current db

    2,run add-migration then comment all codes in UP method in migration file like:

    enter image description here

    3,run update-database

    4,modify the entities and dbcontext accroding to your requirement

    5,run add-migration and update-database again

    You could also try to scaffold dbcontext & entities follow this document

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search