entity framework code first using existing database - asp.net

I have started learning Entity framework and have a problem. I have created a code first mvc project and I don't want to drop the database when the model changes. What can I do other than DropCreateDatabaseIfModelChanges in my initializer class so that the database and the tables stays along with the data?

You don't need to use an initializer at all. This is valid:
Database.SetInitializer<YourContext>(null);
And in your configuration file set AutomaticMigrationsEnabled = false;
Then you can do the migrations yourself.

Related

.Net Core Entity Framework core, using new database for each test in same test class

I have a few tests to test the patching functionality. I am using this custom factory
https://github.com/aspnet/Docs/blob/master/aspnetcore/test/integration-tests/samples/2.x/IntegrationTestsSample/tests/RazorPagesProject.Tests/CustomWebApplicationFactory.cs
For each test, I want to create new database or at-least clear and seed data again. Because other tests are messing up with data.
You can use
db.Database.EnsureDeleted();
This ensures that the database for the context does not exist. If it does not exist, no action is taken. If it does exist then the database is deleted.

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.

There is already an object named 'Applications' in the database

I got this error in my asp.net webapi service when I call method Membership.ValidateUser(email, password);.
I am using EF 4.3.1. DB created using this code
using (var db = DbFactory.Get())
{
Console.WriteLine("Creating new database...");
db.Database.Create();
Console.WriteLine("Initializing with initial objects...");
db.Database.Initialize(true);
}
I get this error only once on first start of my service.
Does anybody know why it happens?
It sounds like you already have an object named 'Applications' in the database the first time your application starts.
Does the code snippet you provided only run at startup?
Try dropping the object through the database management engine, and then re-running your service.
The error is self-explanatory.
You are trying to create an object (ex: table, sp, view, etc.) that is named Applications but that object already exists in the database.
Maybe you didn't remove it after initial testing.
Providing you're trying to run it on the right project:
Check your migrations folder, the Up method of your InitialCreate class is probably trying to create the Application table. You can either
Drop the table and run the code again
or
Set up your InitialCreate properly to handle this scenario

System.InvalidOperationException: Mapping and metadata information could not be found for EntityType

I have an ASP.NET 4.0 web application that uses Entity Framework 4.3.1 and Self-Tracking Entities. It works fine until I add another ADO.NET Entity Data Model (.edmx) file to it. After that the project compiles without any errors, but as soon as it calls a self-tracking entity object, the application produces the System.InvalidOperationException: Mapping and metadata information could not be found for EntityType 'namespace.classname'.
I have tried adding the second ADO.NET Entity Data Model into a different namespace - but that does not help.
If I remove the added .edmx file from the project, the problem disappears.
If I remove the Self-tracking entity files (Model.tt and Model.Context.tt), the problem disappears.
It looks like Self-Tracking Entities cannot function properly when there is more than Entity Data Model.
Has anyone else experienced and solved this problem?
Make sure to use consistent Context generation throughout your solution.
Use the EF 5.x DbContext Generator on each of your Entity Data Models. You can either download the template via the ExtensionManager (search for EF 5.x) or here
I think self tracking entities are not supported from 4.1 (DbContext) onwards.
We had a few problems at work when upgrading from 4 to 4.2 with ste and we ended up reworking all to use DbContext and getting rid of ste. Since then it works like a charm!

EF 4.1 Code First and Existing Database and .NET Membership

I have a database called ApplicationName_Development running on SQL Server 2008 R2 Developer edition on my development box.
I added .NET membership tables to the database with no problem. When I tried to get Code First working I received the following error message:
The server encountered an error
processing the request. The exception
message is "Model compatibility cannot
be checked because the database does
not contain model metadata. Ensure
that IncludeMetadataConvention has
been added to the DbModelBuilder
conventions.
After some googling, I discovered that I had to delete the database and let EF create the database. That's fine but I lost all my .NET membership tables. I can go back in and add the membership tables again but if my model changes and EF needs to recreate the database then I have to add the membership tables in again.
How do I get around this?
This is how code-first work. Main idea of code first is that you do not touch your database because it is responsibility of the model to create the database. If you want to customize your database you must create custom IDatabaseInitializer and add your custom SQL.
public class MyDbInitializer : DropCreateDatabaseIfModelChanges<MyContext>
{
protected override void Seed(MyContext context)
{
// Here run your custom SQL commands
context.Database.ExecuteSqlCommand("CREATE TABLE ....");
}
}
Now you only need setup your cutom intializer on the startup of your application:
Database.SetInitializer<MyContext>(new MyDbInitializer());
If you don't want to do it this way you must manually maintain your database and set initializer to null.
Found a easier workaround here. I hope this helps.
http://www.paragm.com/ef-v4-1-code-first-and-asp-net-membership-service/
Another option could be to use the System.Web.Management namespace. I've had great success with the code below:
string connectionString = ConfigurationManager.ConnectionStrings["MyDatabaseContext"].ConnectionString;
string database = "MyDatabaseName";
SqlServices.Install(database, SqlFeatures.All, connectionString);
It will just create the database and after that you can add users with the standard membership API.
Here's another possibility.
If you look at the MvcMusicStore sample - there's a SampleData class that is responsible for seeding the database on a rebuild. The SampleData class inherits from DropCreateDatabaseIfModelChanges, and overrides the Seed method. This class is passed to the Database.SetInitializer in the Application_Start method in global.asax.
I was getting the same error as you until I changed the parent class of SampleData to CreateDatabaseIfNotExist.
Then you can override the Seed method to insert any data you desire at startup, without it blowing away the database.
While you are developing, create 2 databases and two connection strings. One for SqlMembership (using aspnet_regsql) and one for your EF Application. If you would like to merge them into a single DB in production, just change the connection string in web.config.release to be the same. Then, EF model changes will just drop your apps db and not your membership DB.
By treating your authentication component separately, you will naturally decouple your authentication system from your application system. Then, if you wish to change membership providers, you will be better setup.
As the system grows, you will likely need to support non-pure models without EF code first, so this is a good template for going down that path.
I found the easiest way without playing with anything else was the following.
I ran the application first time with DropAndRecreatedatabase always in the Initilizer.
This created my database for the first time.
Following this I changed this to DropCreateDatabaseIfModelChanges.

Resources