How to create Up and Down Methods using migrations? - c#

I am new to Code first, can you tell me how i can have all Up and Down methods for all tables in the database like below(given for one table)
public partial class abc: DbMigration
{
public override void Up()
{
AddColumn("dbo.UserTasks", "ServiceTechReason", c => c.Long());
}
public override void Down()
{
DropColumn("dbo.UserTasks", "ServiceTechReason");
}
}
i want all three types for a table viz .cs , .Designer.cs , .resx.
2) Can you explain the above example, i pick it from somewhere on internet i was searching for this but found nothing. is abc is my table name in database?
Provide me link if it is already answered.
EDIT
As mentioned by #scheien i already tried those commands they do not automatically override up and down methods for a table

Creating migrations is done by running the command Add-Migration AddedServiceTechReason.
This assumes that you have already enabled migrations using the Enable-Migrations command.
To apply the current migration to the database, you'd run the Update-Database. This command will apply all pending migrations.
The point of Code-First migrations is that you make the changes you want to your Entity(ies), and then add a new migration using the Add-Migration command. It will then create a class that inherits DbMigration, with the Up() and Down() methods filled with the changes you have made to your entity/entities.
As per #SteveGreenes comment: It does pick up all changes to your entities, so you don't need to run it once per table/entity.
If you want to customize the generated migration files, look under the section "Customizing Migrations" in the article listed.
All these commands are run in the package manager console.
View -> Other windows -> Package Manager Console.
Here's a great article from blogs.msdn.com that explains it in detail.

Related

Removing EF Core Migration removes columns the Migration had nothing to do with

I have a class that includes 2 properties: Value and Description. These 2 properties were added to the class a couple of Migrations back and there was never a problem.
Today, while working on a branch I noticed that when I added a new Migration it was scaffolded to once again add the columns, so I started doing some testing.
Starting from the current baseline, with no entity changes, if I add a Migration called "Test", I get this:
using Microsoft.EntityFrameworkCore.Migrations;
namespace AgWare.Data.Migrations
{
public partial class Test : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
}
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}
Which is correct, I haven't made any changes to my Models. Git only shows the new Migration and its Designer.cs files as added, with no changes to the Snapshot. Now, if I run Remove Migration, the Test Migration is removed but suddenly Git says that my Snapshot has changed, with the following lines having been deleted from the modelBulder entry for the above-mentioned class:
b.Property<decimal?>("Value")
.HasColumnType("Money");
b.Property<string>("Description")
.HasMaxLength(75);
So removing a Migration which had nothing to do with these properties somehow results in updating the Snapshot to reflect that they have been removed for some reason. This means when I add another Migration it will generate code to create these columns again, which won't work since they already exist. What could be the cause of this? I want to figure this out now so this doesn't become a reoccurrence for all future Migrations.

EF Core 2.0 update database again, once all migrations run

It's a simple task I think.
My requirement is to run one .sql file after all migrations runs successfully.
it contains few alter statements. the system is in a way that I must have to run this Sql, there are no other way like I just update my entity.
I am using asp.net zero architecture.
Right now I am updating my migrations manually and adding this query's with
migrationBuilder.Sql("");
but it's hard to maintain.
I have done some R&D on this topic but not found anything proper.
as I am following best practice of .net boilerplate structure, I would like to hear from boilerplate dev side too.
You can implement the requirement by creating Stored Procedures or Scalar value function.
Create Empty Migration by running Add-Migration command in
Package Manager Console.
Add the SQL query in Up method like the following way.
public partial class testQuery : Migration {
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql(#"You query");
}
}
Or
Add Stored Procedures folder and testSP.sql inside it. testSP.sql will have whole SP definition.
protected override void Up(MigrationBuilder migrationBuilder)
{
var spPath = #"MyCompany.MyTemplate.EntityFrameworkCore\Migrations\Stored Procedures\testSP.sql";
var spMigratorPath = Path.Combine("..", spPath);
if (!File.Exists(spMigratorPath))
{
spMigratorPath = Path.Combine("..", "..", "..", "..", spPath);
}
migrationBuilder.Sql(File.ReadAllText(spMigratorPath));
}
Run Update-Database in Package Manager Console.
It will create the function or SP in DB.
Now You can call SP by using ExecuteSqlCommand or ExecuteSqlCommandAsync methods.
You can also refer this.

DropCreateDatabaseIfModelChanges when EF is another project

I have separated my solution in separate projects, a DAL project with entity framework and an ASP.NET MVC project.
I want to use DropCreateDatabaseIfModelChanges, but I don't know where to put it to make it work.
I've tried to put it in the web.config of the MVC project and the app.config of the DAL project (both by making use of the context element), I've tried putting it in the global.asax (Database.SetInitializer(new DropCreateDatabaseIfModelChanges<BreakAwayContext>());), I've tried a custom initialization class, but none of these seem to work.
If possible, I don't want to make use of migrations. How can I make it work?
You could create a class to implement CreateDatabaseIfNotExists and call Database.SetInitializer function in Application_Start().
-DbInitializer
public class MyDbInitializer : CreateDatabaseIfNotExists<MyDbContext>
{
protected override void Seed(MyDbContext context)
{
//Data initializing...
}
}
-Application_Start
protected void Application_Start()
{
Database.SetInitializer(new MyDbInitializer());
}
The database will be create when running the application.
And if you would like to do a automatic migration of database, use MigrateDatabaseToLatestVersion class
public class Configuration : DbMigrationsConfiguration<MyDbContext>
{
public Configuration()
{
this.AutomaticMigrationsEnabled = true;
}
}
-Application_Start
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDbContext,Configuration>());
Howerver, I recomand that using migraion commands will be more flexible. See this walkthru: Overview of Entity Framework Code First Migrations with example, by Bhavik Patel.
I guess by 'database initialization' you actually mean 'updating the database schema'.
Set the EfRepository as start up project of the solution
Open the Package manager console Choose EfRepository as default project
Run the following commands:
Enable-Migrations -ConnectionStringName "EfDataRepository"
Add-Migration Initial -ConnectionStringName "EfDataRepository"
Update-Database -ConnectionStringName "EfDataRepository" -Script -SourceMigration:0
This will give you a .sql script. Execute it against your database (and usually store it as part of the solution - either Create.sql or some kind of a migration .sql, depends on whether you already have a schema or you are creating it from scratch).
Of course, replace EfDataRepository with the data connection name from your .config file.

How DbMigrationsConfiguration is related to a DbMigration in EF

In Entity Framework by using Enable-Migrations a Migrations folder is created containing a Configuration inherited from DbMigrationsConfiguration like this:
internal sealed class Configuration : DbMigrationsConfiguration<MyDbContext>
{
...
}
All the created migrations which are created using Add-Migration are placed in the Migrations folder too.
public partial class Init: DbMigration
{
public override void Up()
{
...
}
public override void Down()
{
...
}
}
I didn't find any code that relates these two together ( for example having a configuration property in migrations). The only relation I found is that both are placed in same folder. If I have more than 1 DbContext and consequently more than 1 Configuration, I'm wondering how these DbMigrations are distinguished?
Question: How DbMigration classes are related to a Configuration?
They are related by convention. By default, it will store the migrations in a root folder called Migrations. You can override this in the constructor of the config (https://msdn.microsoft.com/en-us/library/system.data.entity.migrations.dbmigrationsconfiguration(v=vs.113).aspx) or when you enable-migrations:
public Configuration()
{
AutomaticMigrationsEnabled = true;
MigrationsDirectory = #"Migrations\Context1";
}
For multiple contexts, create a different config and folder for each by using -ContextTypeName ProjectName.Models.Context2 -MigrationsDirectory:Migrations\Context2. Here is a walkthrough: http://www.dotnettricks.com/learn/entityframework/entity-framework-6-code-first-migrations-with-multiple-data-contexts
When you run the update-database command, the database operations in the up() method in the latest DbMigration derived classes is performed. If that is successful, the commands in the Configuration class are executed. One of those methods is the seed() method where you can optionally add code to plug values into your tables after a migration. When you specify a target migration (presumably earlier than the latest), the migration works through the chain of down() methods in the migration classes to get to the version you wanted.

Can't make EF Code First work with manually changed data base

I've added two new properties to my domain model class and two properties to a data table accordingly. Then I tried to launch my mvc web application and got
The model backing the 'EFDbContext' context has changed since the database was created.
Consider using Code First Migrations to update the database
(http://go.microsoft.com/fwlink/?LinkId=238269).
Having read the following posts:
MVC3 and Code First Migrations
EF 4.3 Automatic Migrations Walkthrough
I tried to Update-Database through Package Manager Console, but got an error
Get-Package : Не удается найти параметр, соответствующий имени параметра "ProjectName".
C:\Work\MVC\packages\EntityFramework.5.0.0\tools\EntityFramework.psm1:611 знак:40
+ $package = Get-Package -ProjectName <<<< $project.FullName | ?{ $_.Id -eq 'EntityFramework' }
+ CategoryInfo : InvalidArgument: (:) [Get-Package], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,NuGet.PowerShell.Commands.GetPackageCommand
The EntityFramework package is not installed on project 'Domain'.
But the Entityframework is installed on project Domain. I removed it from references, deleted package.config and sucessfully reinstalled EF. But Update-Database still returns same error. Update-Database -Config does as well
What am I doing wrong?
EDIT
Many thanks to Ladislav Mrnka, I'll try to rephrase my question. As far as I changed my data table manually, I am not expected to use migration. But how can I now make EF work with manually edited domain model class and data table?
Try to add this to startup of your application (you can put it to App_Start):
Database.SetInitializer<EFDbContext>(null);
It should turn off all logic related to handling the database from EF. You will now be fully responsible for keeping your database in sync with your model.
I had the same problem and this is how I fixed the issue.
I dropped table __MigrationHistory using sql command and run the update-database -verbose again.
Apparently something was wrong with this automatic created table.
Answer 2 was exactly what was needed. Although when I got to the App_Start I realized that there were 4 configuration files and didn't see where this would fit in any of them. Instead I added it to my EF database context
namespace JobTrack.Concrete
{
public class EFDbContext : DbContext
{
//Set the entity framework database context to the connection name
//in the Webconfig file for our SQL Server data source QSJTDB1
public EFDbContext() : base("name=EFDbConnection")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//Remove the tight dependency on the entity framework that
//wants to take control of the database. EF by nature wants
//to drive the database so that the database changes conform
//to the model changes in the application. This will remove the
//control from the EF and leave the changes to the database admin
//side so that it continues to be in sync with the model.
Database.SetInitializer<EFDbContext>(null);
//Remove the default pluaralization of model names
//This will allow us to work with database table names that are singular
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
//Allows for multiple entries of the class State to be used with
//interface objects such as IQueryTables for the State database table
public DbSet<State> State { get; set; }
}
}

Categories