is it possible to use sql files as EF database migrations? - c#

I'm using EF6.0 and implementing my db with SQLServerDatabaseProject.
I want to use the EF Migration tools for Database migration. but since I have my database on DbProject I want all my migration files to be SQLFiles (not c#)
So I would like to know if EF supports this feature and if not, is it possible to write a new Migration class which keeps the EF features but works this way?
Please also consider that I don't want EF to generate my migrations but I would like to be able to use other migration commands such as update-database and ...
==MORE DETAILS ABOUT THE QUESTION==
I don't want to have c# classes load my sql files. The sql files must be saved for up and down migrations directly and be treated exactly as if they are the DbMigration classes.
A simple example of Migrations dir would be something like this:
Migrations
-> up
-> 201510060807125_alter-course-change-family.sql
-> 201510060813136_alter-course-add-mark-column.sql
-> down
-> 201510060807125_alter-course-change-family.sql
-> 201510060813136_alter-course-add-mark-column.sql

Simply in the migration class use SqlFile extension method:
public partial class MyFancyMigration : DbMigration
{
public override void Up()
{
SqlFile("myUpSQLFile.sql");
}
public override void Down()
{
SqlFile("myDownSQLFile.sql");
}
}

Although you can use SqlFile method, I suggest you to write this on Seed method of your Configuration.cs file in your migration folder.
internal sealed class Configuration : DbMigrationConfiguration<YourDbContext>
{
protected override void Seed(YourDbContext context)
{
base.Seed(context);
context.Database.ExecuteSqlCommand(FileReadAllText("migration.sql"));
}
}
If you write migrations in Up method. It will be executed per each migration when you update the database, which I think you don't expect.
What you want is that your scripts run per each Update-Database. (Not per each migration in it)

Related

Updating a SQLite Database to reflect a change to the model with Entity Framework Core and .NET 6

I've created a dbcontext that looks like this:
public class DatabaseContext : DbContext
{
public DbSet<Author> Authors { get; set; }
public DbSet<Book> Books { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite(#"Data Source=E:\Portfolio\FullStack\HomeLibraryManager\Database\Library.db;");
}
}
And I Initialize it like this:
using (var context = new DatabaseContext())
{
context.Database.EnsureCreated();
var books = context.Books.ToList();
}
I would like to add a variable to my Book class but how do I get the database table to have that new variable added as a column.
I had hoped that EnsureCreated() would make sure the table columns were updated if needed but it seems not.
Any help would be great,
thanks
Edit Solution:
I used context.Database.Migrate(); instead of EnsureCreated and ran dotnet-ef migrations add [MigrationNameHere] first
Run the Add-Migration AddUrl command in Package Manager Console. The Add-Migration command checks for changes since your last migration and scaffolds a new migration with any changes that are found. We can give migrations a name; in this case we are calling the migration ‘AddUrl’. The scaffolded code is saying that we need to add a Url column, that can hold string data, to the dbo.Blogs table. If needed, we could edit the scaffolded code but that’s not required in this case.
Run the Update-Database command in Package Manager Console. This command will apply any pending migrations to the database. Our InitialCreate migration has already been applied so migrations will just apply our new AddUrl migration. Tip: You can use the –Verbose switch when calling Update-Database to see the SQL that is being executed against the database.
Dealing with Model Changes

Entity Framework Database First - How to prevent running the initial migration?

I was able to scaffold an existing database using EF Core recently. We want to completely migrate to EF Core, but we've hit some snags and I need your help.
We began by running the scaffold command and ended up with this file structure
C:\>ls .\EFCore
Context
Models
EFCore.csproj
Then after creatinng the Context and the Models, I ran the inital migration command.
dotnet ef migrations add CreateDb
After running that command our directories look like this
C:\>ls .\EFCore
Context
Models
Migrations
EFCore.csproj
C:\>ls .\EFCore\Migrations
20210616210256_CreateDb.cs
20210616210256_CreateDb.Designer.cs
DbContextModelSnapshot.cs
My Problem
The database is already created in all environments, so we don't want entity to execute the inital database migration. Should I delete 20210616210256_CreateDb.cs and 20210616210256_CreateDb.Designer.cs to achieve this?
The other route I can think of is create the __EFMigrationsHistory table and insert a row into it. This would fake that we've already ran the inital db create.
Help please, I would like to do this the cleanest way possible.
Remove/Comment the code inside your Up() and Down() methods of migration file and call update database. You don't want the code which creates table i.e.
CreateTable(
"dbo.YourTable",
c => new
{ //Properties set here })
Your migration class could look like this -
public partial class Initial : DbMigration
{
public override void Up()
{
}
public override void Down()
{
}
}

Entity Framework Core - Custom Migration stopped working

For a while now I've had a custom migration in my Entity Framework Core project that creates some SQL objects - stored procedures and functions.
It looks something like this:
using Microsoft.EntityFrameworkCore.Migrations;
namespace CaseFlow_API.Migrations
{
public partial class AdditionalSQLObjects : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
// Functions
var f_exampleFunction = #"CREATE OR REPLACE FUNCTION public.f_exampleFunction(
character varying,
character varying,
character varying,
integer)
/*
SOME SQL CODE
*/
";
migrationBuilder.Sql(f_exampleFunction);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}
However now it stopped working - functions and procedures are not created when updating the db. I don't think I changed anything in how migrations are created. What I would do usually is that I'd run
dotnet ef migrations add Initial
dotnet ef database update
I tried dropping all migrations, dropping the database, recreating the AdditionalSQLObjects.cs class. I have no idea how to debug/fix this.
Can you please point me to places where I can fix this?
Ok, so the custom migration finally works. Here's what I did (added class attributes):
[DbContext(typeof(CaseflowingContext))]
[Migration("CustomMigration_AdditionalSQLObjects")]
public partial class AdditionalSQLObjects : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
//miration code
}
}
I have no idea what happened, because this migration used to work without the attributes, but I'll take it.

Why is Entity Framework's migrations Configuration.cs file located and executed automatically?

I have a C# project where I'm using Entity Framework 6.1. I have a few migration files and a Configuration.cs file within the same folder. Configuration.cs contains the following class:
namespace SNS.Database.Migrations
{
public class Configuration : DbMigrationsConfiguration<SNSContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(SNSContext context)
{
...
}
}
}
If I understand Entity Framework correctly, the Seed method is supposed to be executed after a new database migration file has been applied. Furthermore, to configure this, it's done with the following call:
System.Data.Entity.Database.SetInitializer(new MigrateDatabaseToLatestVersion<SNSContext, Configuration>());
That works fine. However, the Seed method does always get called, even if I haven't made the SetInitializer call.
So my question is, what tells Entity Framework to run Configuration.cs, and why does it always execute the Seed method?
I have already checked in my App.config file, and it doesn't specify codeConfigurationType.

How to force a new empty EF Migration?

Ok, so I'm relying completely on my migrations and seed code to maintain all database structure and initial data. Because of that, I'm facing a situation where all the changes I'm doing at this version are made directly on the database (Stored Procs and Updates) and nothing has changed on the C# code itself.
The question is: Since I want to do those DataBase specific changes using a new migration (and an "add-migration" will do nothing - cause the code hasn't change), how can I force a new empty code first migration to put my changes manually on it?
In the package manager console issue the command
Add-Migration "My new empty migration"
This will generate this migration template
public partial class Mynewemptymigration : DbMigration
{
public override void Up()
{
}
public override void Down()
{
}
}
You can then create your own custom up and down migration steps. If you model is not up to date there will be migration code in the up and down. In that case you'll have to get your model up to date and then add a new empty migration.
You have to add an empty migration and add the code to the Up and Down method manually. I have found that people tend to think that the code for those methods have to be generated by the tool similar to ".designer" files and this is not the case. In fact more often than not i have found my self editing and adding code there.
For this purpose I place all the sql code that i have to execute in scripts files and the execute then in the Up methods like this:
public override void Up(){
var dirBase = AppDomain.CurrentDomain.BaseDirectory.Replace(#"\bin",string.Empty) + #"\Migrations\SqlScripts";
Sql(File.ReadAllText(dirBase + #"\CreateMyViews.sql"));
Sql(File.ReadAllText(dirBase + #"\CreateMySproc.sql"));
}
public override void Down(){
var dirBase = AppDomain.CurrentDomain.BaseDirectory.Replace(#"\bin",string.Empty) + #"\Migrations\SqlScripts";
Sql(File.ReadAllText(dirBase + #"\DropMySproc.sql"));
Sql(File.ReadAllText(dirBase + #"\DropMyViews.sql"));
}
I recomend you read this link:
http://elegantcode.com/2012/04/12/entity-framework-migrations-tips/
This is a more up-to-date answer...
In Package Manager Console in Visual Studio, add an empty migration targeting your Database context.
add-migration SeedingFacilityTable -context YourDbContextName
It'll create an empty migration provided you don't have any other DB changes to be applied.
Inside the Up method, write the following:
public partial class SeedingFacilityTable : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql(#"Put as many SQL commands as you want here");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
Then run the following command:
update-database -context YourDbContextName
Add-migration actually do exactly what's asked for.
You can just run dotnet ef migrations add or Add-Migration in the package manager console (as mentioned by David) to generate a class with empty Up and Down methods. Then just put your changes inside that class as usual.

Categories

Resources