I´ve got a little program, which uses EFCore 5.0.12 also I have added a Company and Person model to the program which are my DB-Models. Then I´ve added a migration to initial create the tables.
Then I´ve added an Address model for the Person model, which should also be a DB-Model. The did a second migration, which you can see below. But if I run my code again it seems like it want to migrate both Migrations.
How can I migrate a Database from specific migration.
Here my code:
This is my TestDbContext which should do all the Db-work.
public class TestDbContext : DbContext
{
public DbSet<Company> Companies { get; set; }
private string _dbPath = Path.Combine(".", "TestDb.sqlite");
public TestDbContext()
{
if (File.Exists(_dbPath))
Database.Migrate();
else Database.EnsureCreated();
}
protected override void OnConfiguring(Microsoft.EntityFrameworkCore.DbContextOptionsBuilder optionsBuilder)
{
if (!Directory.Exists(Path.GetDirectoryName(_dbPath)))
Directory.CreateDirectory(Path.GetDirectoryName(_dbPath));
try
{
optionsBuilder.UseSqlite($"Data Source={Path.GetFullPath(_dbPath)}");
}
catch (Exception ex)
{
//Log.Error("Could not create DB");
//Log.Error(ex);
return;
}
}
Also I´ve got this Company-Model which inherits from BaseEntry which holds an ID field as
public class Company : BaseEntry
{
public List<Person> Employees { get; set; } = new List<Person>();
}
The Person-Model also inherits from BaseEntry to get a PrimaryKey also.
public class Person : BaseEntry
{
public string Name { get; set; }
public string Firstname { get; set; }
public Address Address { get; set; }
}
Address which should be added while migration.
public class Address : BaseEntry
{
public string Street { get; set; }
public uint Number { get; set; }
public string City { get; set; }
}
And the BaseEntry which holds the ID field.
public abstract class BaseEntry
{
[Key]
public ulong Id { get; set; }
}
Here comes the first migration which ensures the tables content
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Companies",
columns: table => new
{
Id = table.Column<ulong>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true)
},
constraints: table =>
{
table.PrimaryKey("PK_Companies", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Person",
columns: table => new
{
Id = table.Column<ulong>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Name = table.Column<string>(type: "TEXT", nullable: true),
Firstname = table.Column<string>(type: "TEXT", nullable: true),
CompanyId = table.Column<ulong>(type: "INTEGER", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Person", x => x.Id);
table.ForeignKey(
name: "FK_Person_Companies_CompanyId",
column: x => x.CompanyId,
principalTable: "Companies",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex(
name: "IX_Person_CompanyId",
table: "Person",
column: "CompanyId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Person");
migrationBuilder.DropTable(
name: "Companies");
}
}
Then here the second migration, which adds the Adress-Content to the DB:
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<ulong>(
name: "AddressId",
table: "Person",
type: "INTEGER",
nullable: true);
migrationBuilder.CreateTable(
name: "Address",
columns: table => new
{
Id = table.Column<ulong>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Street = table.Column<string>(type: "TEXT", nullable: true),
Number = table.Column<uint>(type: "INTEGER", nullable: false),
City = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Address", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_Person_AddressId",
table: "Person",
column: "AddressId");
migrationBuilder.AddForeignKey(
name: "FK_Person_Address_AddressId",
table: "Person",
column: "AddressId",
principalTable: "Address",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Person_Address_AddressId",
table: "Person");
migrationBuilder.DropTable(
name: "Address");
migrationBuilder.DropIndex(
name: "IX_Person_AddressId",
table: "Person");
migrationBuilder.DropColumn(
name: "AddressId",
table: "Person");
}
}
But this migration is never reached because the first migration fails because of Table already exists. My main question is, how to say EFCore that the DB is allready migrated to a specific point and it should only migrate from this point?