How to initializing the code-first Entity Framework database in an Azure Mobile Services project - ef-code-first

I am utterly confused by the use of Entity Frameworks code-first migrations within Azure Mobile Services.
I'm following the article How to make data model changes to a .NET backend mobile service with additional help from Stack Overflow answers, and have also read Code First Migrations and Code First Migrations in Team Environments and watched Migrations - Under the Hood.
In Visual Studio 2015 I make a new Azure Mobile Service, and then enable code-first migrations by going to the nuget Package Manager Console (PMC) and running Enable-Migrations. I then build and run the project. Then to make the database I create an initial migration with the PMC command Add-Migration Initial and apply it with the PMC command Update-Database -Verbose -TargetMigration Initial.
This fails with the error message
Cannot create more than one clustered index on table
'MobileService1.TodoItems'. Drop the existing clustered index
'PK_MobileService1.TodoItems' before creating another.
As I used the Verbose flag I can see the auto-generated SQL and indeed plugging that into a query and running it against a freshly minted database produces the same error because the primary key already provides a clustered index.
CREATE TABLE [MobileService1].[TodoItems] (
[Id] [nvarchar](128) NOT NULL,
[Text] [nvarchar](max),
[Complete] [bit] NOT NULL,
[Version] rowversion NOT NULL,
[CreatedAt] [datetimeoffset](7) NOT NULL,
[UpdatedAt] [datetimeoffset](7),
[Deleted] [bit] NOT NULL,
CONSTRAINT [PK_MobileService1.TodoItems] PRIMARY KEY ([Id])
)
CREATE CLUSTERED INDEX [IX_CreatedAt] ON [MobileService1].[TodoItems]([CreatedAt])
However the article does warn me to make a change: replace Database.SetInitializer(new MobileServiceInitializer()); in MobileService1.WebApiConfig.Register with
var migrator = new System.Data.Entity.Migrations.DbMigrator(new Migrations.Configuration());
migrator.Update();
But after making that change I get exactly the same error when I run Update-Database -Verbose -TargetMigration Initial at the PMC.
Another suggestion, from Dominique Alexandre's comment on his question Running Azure Mobile Server project locally is to instead replace Database.SetInitializer(new MobileServiceInitializer()); in MobileService1.WebApiConfig.Register with
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MobileServiceContext, Migrations.Configuration>());
But again I get exactly the same error.
What should I be using? Is there a simple way through Entity Frameworks code-first migrations as used in Azure Mobile Services?

The specific error that you're seeing is due to the fact that EF assumes primary keys are also clustered indexes and there's no way to signal that this isn't the case. Things work when you perform automatic migrations because when the app starts, Mobile Services/Apps registers a custom SqlGenerator that removes the clustered index (along with a few other important things). This custom SqlGenerator isn't used by migrations by default.
However, you can tell your migration to use this same SqlGenerator by specifying it in the Migrations\Configuration.cs file:
// Mobile Services namespace:
// using Microsoft.WindowsAzure.Mobile.Service.Tables
// Mobile Apps namespace:
// using Microsoft.Azure.Mobile.Server.Tables;
---<snip>---
public Configuration()
{
AutomaticMigrationsEnabled = false;
SetSqlGenerator("System.Data.SqlClient", new EntityTableSqlGenerator());
}
Give that a try. The resulting db should include the CreatedAt trigger and other SQL-specific settings that Mobile Services/Apps expects. Let me know if you bump into issues doing this and I can look further.

After trying every solution I can find, , I found the magic is located in these lines (from the Quickstart project)
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Add(
new AttributeToColumnAnnotationConvention<TableColumnAttribute, string>(
"ServiceTableColumn", (property, attributes) => attributes.Single().ColumnType.ToString()));
base.OnModelCreating(modelBuilder);
}
(add to your context class)
This solved the clustered error problem.
(I'm working with Azure Mobile Apps not Mobile Services)

I just tested this and I also get this error when using Update-Database in PMC.
I'm using Azure Mobile Apps, not Services, but it's the same Entity-Data.
Starting from an empty table, what works for me is just having an Initial Migration file, a Configuration.cs and the MigrateDatabaseToLatestVersion bit. Then you can just run the application with F5 instead of Update-Database.
It should create your schema along with your seed.

Related

MigrateDatabaseToLatestVersion seed() doesn't create tables in database [duplicate]

In my application I enable Code First Migrations with some migrations, Also I use SQL Server Compact for integration test.
When I run my tests, Entity Framework create an empty database and tries to run migration on that empty database and thrown The specified table does not exist.
Based on this report I think usage of Migration in Entity Framework 6 has changed.
I test all Database Initializer with Context.Database.Create(); but in all case tabale's never created.
I don't know that this is EntityFramework's bug or not, but when I made rename the namespace of Migration Configuration class from default (Projectname/Migrations) to any none default name, migration works well.
Context.Database.Create() will not execute migrations! It only creates empty db. To Update database from code to latest version you need to use DbMigrator.Update method:
var migrator = new DbMigrator(new MyMigrationsConfiguration());
migrator.Update();
Alternatively you might use MigrateDatabaseToLatestVersion
Database.SetInitializer(new MigrateDatabaseToLatestVersion<BlogContext, Configuration>());
It is described in details here: http://msdn.microsoft.com/en-us/data/jj591621.aspx#initializer
In case someone still struggles to fix the issue.
The code that follows works for me: add-migration MyFirstMigration
Meanwhile add-migration "MyFirstMigration" with the migration name ramped in quote doesn't work.
There may be previous migration files which the ide may be referring to mostly likely due to caching.
Drop backup and drop target database if it exists, and drop the migration folder.
Now add the migration and you will be good to go.
It does happens when adding model and running add-migration command.
Here is the simplest cause of this issue:
Add a newly added model property into IdentityDbContex class.
Here are the steps:
create model
add property into IdentityDbContex class
run add-migration
update-database

Flyway: non-empty schema without metadata table

Found non-empty schema "public" without metadata table! Use init() or set initOnMigrate to true to initialize the metadata table.
I'm using Postgres 9.2 with Postgis 2.0. This means that by default when I create a new database there will be a table created in public schema called spatial_ref_sys.
When I run flyway migrate on this database, I get the above error. Running init seems to create the public.schema_version table and mark version 1 as SUCCEDED without actually running the the migration file. I've also tried combinations of initOnMigrate with no success. Flyway is not configured to manage any schemas.
Any ideas on how I can run a migration in this scenario?
The title is somewhat contradictory, as the database is indeed not virgin as you installed, through the PostGIS extension, a number of objects in the public schema.
You can either
set flyway.schemas to a new schema, say my_app, which will then be created automatically by Flyway. Your application should then use this one instead of public (recommended)
set flyway.baselineOnMigrate to true or invoke flyway.baseline() against the public schema. This will work, but public will then contain a mix of both your application objects and the PostGIS objects
If you are using Gradle you can run
./gradlew -Dflyway.schemas=public flywayClean flywayMigrate
Where public is the name of the database containing the schema_versions table. That should delete the table and metadata as well as running the migrations to get it back up to date.
Caution!
This will delete all data in public schema
I think this error comes only with latest version of Flyway i.e. above 4.03. I didn't received in the earlier project but got it when I am using Flyway version 5.07 in my latest project. Putting the code here that resolve my issues
public class FlywayConfig {
#Autowired
DataSource dataSource;
#Autowired
Config config;
#Bean
public Flyway flyway(){
Flyway flyway = new Flyway();
flyway.setDataSource(dataSource);
flyway.setSqlMigrationPrefix("V");
flyway.setLocations(new String[] { config.getSqlLocation() });
flyway.setBaselineOnMigrate(true);
// *******************flyway.clean(); ********************// this will wipe out the DB, be careful
flyway.migrate();
return flyway;
}
}
this work for me , i were figthin with the same problema a lot of time
my project was building on maven
Flyway flyway = new Flyway();
flyway.setDataSource(dataSource);
flyway.setLocations("db/your_db");
flyway.setTable("name_of_schema");
next a added this line
flyway.setBaselineOnMigrate(true);
flyway.clean();
next this lines
MigrationInfo migrationInfo = flyway.info().current();
flyway.migrate();
and i let you the URL of my references from flyway.org
Flyway.org/documentation/commandline/baseline
In my case the problem started when I deleted all the rows in the table myschema.schema_version
./gradlew flywayInit did the trick and the error is not showed anymore.

Can you create a database without migrations in EF5?

I am following the offical asp.net "Getting started with EF 5 using MVC 4". In that tutorial, the database is created when the migrations are performed(in my understanding). When I was looking at the EF 5 with Mvc 5 tutorial they didn't use migrations to create a database. They use database initializer. So, I was wondering could create a database for your project without using migrations in EF 5? Also, what would the difference be with both these approaches?
Code first Migrations and using Package Manager Console Commands to do upgrades can get a bit confusing at first.
You can use the initializer to CreateDatabaseIfNotExists , DropCreateIfModelChanges, DropCreateDatabaseAlways and to MigrateDatabaseToLatestVersion
See the interface IDatabaseInitializer<TContext>.
CreateDatabaseIfNotExists // is the Default initializer.
So this is why it appears EF just does things for you sometimes.
So the answer is "YES you can "Create a Database without Migrations"
But the difference is not obvious and if you would do that long term is another question.
If you are using migrations. It would Update the Db to match the code first model.
If there is NO database, then that means creating the database.
So Thats why Automated migrations and CreateDB look confusing since they can result in same outcome sometimes. But technically they are different.
So generally it is sufficient to use code first automatic "migrations" only.
Migrations can be either Automatic or "managed".
The managed migrations approach invovles generating code , tweaking the code and running PM commandlet or POwershell command to actually perform the migration.
With Automated migrations you just need set the intitializer and Access the DBContext.
There are 2 parts to the process.
a) The DB Initializer step.
do this immediately before instantiating YourDBContext.
//eg
// DONT TOUCH MY DB or i break your back!
Database.SetInitializer(new ContextInitializerNone<YourDbContext>()); // Do Nothing,
// OR
// yes migrate my db to match my code please.
Database.SetInitializer(new MigrateDatabaseToLatestVersion<YourDbContext, YourMigrationConfiguration>()); // Set to migration is requested, see config class below
The Confirguration class specified when using Migration initializer looks like this
public class YourMigrationConfiguration<TContext> : DbMigrationsConfiguration<TContext>
where TContext : DbContext{
protected YourMigrationConfiguration() {
AutomaticMigrationsEnabled = true; // run it when needed. Do not wait for my PM Command
AutomaticMigrationDataLossAllowed = true; // if the new db look means dropping tables or columns go ahead and kill my data. So use this option with caution.
}
then just trigger the migration in code when required.
Context.Database.Initialize(true); // i place this inside a method on my UoW class
Code first Db initialization strategies.
Code first migrations recommended reading
Managed Migrations
There are many articles on the web on this topic.

How to delete and recreate from scratch an existing EF Code First database

I am using EF Code First with EF 5 in VS 2012. I use PM update-database command and I have a simple seed method to fill some tables with sample data.
I would like to delete and recreate my x.mdb. The update history seems to be out of sync. If I comment out all my DBSets in my context, update-database runs with no error but leaves some tables in the DB. As I have no valuable data in the DB it seems to the simplest to reset the all thing.
How can I accomplish this?
If I'm understanding it right...
If you want to start clean:
1) Manually delete your DB - wherever it is (I'm assuming you have your connection sorted), or empty it, but easier/safer is to delete it all together - as there is system __MigrationHistory table - you need that removed too.
2) Remove all migration files - which are under Migrations - and named like numbers etc. - remove them all,
3) Rebuild your project containing migrations (and the rest) - and make sure your project is set up (configuration) to build automatically (that sometimes may cause problems - but not likely for you),
4) Run Add-Migration Initial again - then Update-Database
If you worked the correct way to create your migrations by using the command Add-Migration "Name_Of_Migration" then you can do the following to get a clean start (reset, with loss of data, of course):
Update-database -TargetMigration:0
Normally your DB is empty now since the down methods were executed.
Update-database
This will recreate your DB to your current migration
For EntityFrameworkCore you can use the following:
Update-Database -Migration 0
This will remove all migrations from the database.
Then you can use:
Remove-Migration
To remove your migration.
Finally you can recreate your migration and apply it to the database.
Add-Migration Initialize
Update-Database
Tested on EFCore v2.1.0
Similarly for the dotnet ef CLI tool:
dotnet ef database update 0 [ --context dbcontextname ]
dotnet ef migrations add Initialize
dotnet ef database update
Single Liner to Drop, Create and Seed from Package Manager Console:
update-database -TargetMigration:0 | update-database -force
Kaboom.
How about ..
static void Main(string[] args)
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<ExampleContext>());
// C
// o
// d
// i
// n
// g
}
I picked this up from Programming Entity Framework: Code First, Pg 28 First Edition.
dbctx.Database.EnsureDeleted();
dbctx.Database.EnsureCreated();
I am using .net Core 6 and this code is directly stripped out of the Program.cs
using Microsoft.EntityFrameworkCore;
namespace RandomProjectName
{
public class Program
{
public static async Task<int> Main(string[] args)
{
var connectionString = "Server=YourServerName;Database=YourDatabaseName;Integrated Security=True;";
var optionsBuilder = new DbContextOptionsBuilder<YourDataContext>();
optionsBuilder.UseSqlServer(connectionString);
var db = new YourDataContext(optionsBuilder.Options);
db.Database.EnsureDeleted();
db.Database.Migrate();
}
}
}
You should have at minimum initial migration for this to work.
There re many ways to drop a database or update existing database, simply you can switched to previous migrations.
dotnet ef database update previousMigraionName
But some databases have limitations like not allow to modify after create relationships, means you have not allow privileges to drop columns from ef core database providers but most of time in ef core drop database is allowed.so you can drop DB using drop command
and then you use previous migration again.
dotnet ef database drop
PMC command
PM> drop-database
OR you can do manually deleting database and do a migration.
If you created your database following this tutorial: https://msdn.microsoft.com/en-au/data/jj193542.aspx
... then this might work:
Delete all .mdf and .ldf files in your project directory
Go to View / SQL Server Object Explorer and delete the database from the (localdb)\v11.0 subnode. See also https://stackoverflow.com/a/15832184/2279059
Using EF6 with ASP.Net Core 5 I found these commands handy during first initialization of the database:
Remove-Migration -force; Add-Migration InitialMigration; Update-Database;
It removes the last migration (should be the only one), creates it again, then refreshes the database. You can thus type these three commands in one line into the Package Management Console after editing your DbContext and it'll update InitialMigration and database.
A little annoying is that it'll compile your project three times in a row but a least no further manual steps (like deleting the migration files) are necessary.
When you remove an entity you'll need to issue Remove-Database before updating. So the line becomes:
Remove-Migration -force; Add-Migration InitialMigration; Remove-Database; Update-Database;
Problematic here: You need to confirm removing the database + 4 rebuilds.
Take these steps:
Delete those object which should be deleted from the context // Dbset<Item> Items{get;set;}
and in Nuget Console run these commands
add-migration [contextName]
update-database -verbose
It will drop table(s) that not exist in Context, but already created in database
Let me help in updating the answers here since new users will find it useful.
I believe the aim is to delete the database itself and recreate it using EF Code First approach.
1.Open your project in Visual Studio using the ".sln" extention.
2.Select Server Explorer( it is oftentimes on the left)
3.Select SQL Server Object Explorer.
4.The database you want to delete would be listed under any of the localDB. Right-Click it and select delete.
Since this question is gonna be clicked some day by new EF Core users and I find the top answers somewhat unnecessarily destructive, I will show you a way to start "fresh". Beware, this deletes all of your data.
Delete all tables on your MS SQL server. Also delete the __EFMigrations table.
Type dotnet ef database update
EF Core will now recreate the database from zero up until your latest migration.

Entity Framework 5 Code First Database Initialization Strategy

Hello I'm starting a new project and I have been really struggling to get a good database initialization algorithm.
What I want is to Drop/Create every time the app initializes. And then run migrations.
So my ideal workflow is (as the app starts up):
1. Drop database if it exists
2. Create database from model classes
3. Initialize web security (ASP.NET roles provider)
4. Run Migration script
3 and 4 could be interchanged.
The problem I have is that either migrations don't get run, or the drop database if it exists doesn't get run. (And there is some trickery involved with the initialization of web security because it MUST be run after the database has been created so it can add foreign key constraints on the UserProfile table created in step #2.
I believe one possible reason for my difficulty is because Migrations were never intended to run in conjunction with a Drop/Create policy. The reason I need Migrations to run for a brand new project is I want to specify an index on a column. So far the only way I know how to do this is in the migration script:
public override void Up()
{
CreateIndex("dbo.UserProfile", "UserName", true);
}

Resources