We are using the Code-first approach without an Edmx file, its running fine to create database the first time.
But if I am adding new data entities say new class to my database context then it is not able to add that to new table in that database.
Say for example there are two table initially in database.
ex Database : DbTest
Table : Tbl1, Tbl2
Now if I add new table, say class name 'Tbl3', then it should be adding it into the existing database.
Can any one please explain to me with an example how it can be achieved via code first approach?
I have seen mentioned something like Database.SetInitializer(new ........)
What do I need to put in the blank area of the constructor above?
If you look in your database you will see a table called "EdmMetadata" which Entity Framework uses to determine if any changes have been made to your model since the database was created (which it has in your case).
The default behaviour is for an exception to be thrown if the model and database differ. To get different behaviour you will need to use an IDatabaseInitializer<TContext>.
Luckily, Entity Framework ships with some default implementations of this interface:
CreateDatabaseIfNotExists<TContext> - This will create the database if one doesn't already exist.
DropCreateDatabaseAlways<TContext> - This will re-create the database each time your application is run.
DropCreateDatabaseIfModelChanges<TContext> - This will re-create the database if a change is detected in the EdmMetadata table (usually as a result of creating new tables).
You can of course also create your own implementation of this interface by overriding the InitializeDatabase method.
an example of using one of these initialization strategies is shown below:
Database.SetInitializer(
new DropCreateDatabaseIfModelChanges<NameOfYourDbContextClass>())
Think carefully before choosing an initialization strategy as you could end up losing data already entered into the database and this may not be what you want.
The implementations provided by Entity Framework provide a Seed method for loading your database with data so that you can preload your database with default data each time it is created.
This article provides further information.
Related
We are using Entity Framework Core 2.2 with code first. Sometimes I change one of the entities, but forget to create a new migration, or I create a migration but only in one context (we have for different db engines). I want to check it automatically (ideally as NUnit test) so it runs in our CI server for every commit.
Manually I would try to create a new migration and check that created Up() and Down() methods are empty. It there any way to do it as a NUnit test?
Where is difficulty in creating a test that :
Creates a new DB
Applies all current migrations to create a schema
Tries to use all the entities. It can be as simple as adding an entity, querying that entity and deep-comparing they are the same.
Drops the DB
If the schema doesn't have a migration for new entity or change in entity, you are sure to get and SQL error out of this.
Sure, every time you create a new entity, you would need to add a new test. But that should be already happening if you are using TDD.
And speed shouldn't be a problem either, as creating and dropping a DB shouldn't take more than few seconds and there won't be many of these kind of tests. And they can be parallelized.
If you want to get fancy and don't want to write test for each entity, it could be possible to do something like this :
Use reflection to get all entity types supported by a Context.
Use auto data generator like Bogus or AutoFixture to fill the entities with data.
Round-trip the entities through DB.
Compare the original with retrieved using deep-comparer like Compare-Net-Objects.
The usefulness of such automated approach would depend on complexity of your data model. Would just work for simple model. But would require lots of tweaking and overrides if the model is complex.
I am writing a service that will decide at some point it needs to store values and so needs to create tables inside an existing database. Later on, it will decide it no longer needs this storage and so should remove those tables. This cycle could repeat multiple times. I am using EF6 to simplify the database operations.
Creating the tables is easy as the first time the DbContext is used it will automatically create the tables along with the initial migration record. To avoid having to create verbose migration classes I just derive from a class from DbMigrationsConfiguration and then set the AutomaticMigrationsEnabled to true. Then it generates the tables using the code first model classes.
The problem is that later on I need to remove these tables and the matching migration record. There does not seem to be any useful method for doing that. The closest I found was DbContext.Database.Delete(). This is not appropriate because it attempts to delete the entire database and this is not possible because the database has lots of other tables used for other purposes.
Is there no way to tell EF6 to remove all the tables and migration record for a DbContext? That seems a strange omission. I do not want lots of zombie tables lingering that are no longer needed. Not everyone can create and delete an entire database to support a single DbContext.
I want to use Code First Technique of EF6 but when i made changes to table, it drops the database and recreates it, wiping out all data.
Is there any way to stop this from happening?
My Code :
Database.SetInitializer<EmployeeDb>(new DropCreateDatabaseIfModelChanges<EmployeeDb>());
These are the strategies for database initilization in code first approach:
CreateDatabaseIfNotExists: This is default initializer. As the name suggests, it will create the database if none exists as per the configuration. However, if you change the model class and then run the application with this initializer, then it will throw an exception.
DropCreateDatabaseIfModelChanges: This initializer drops an existing database and creates a new database, if your model classes (entity classes) have been changed. So you don't have to worry about maintaining your database schema, when your model classes change.
DropCreateDatabaseAlways: As the name suggests, this initializer drops an existing database every time you run the application, irrespective of whether your model classes have changed or not. This will be useful, when you want fresh database, every time you run the application, like while you are developing the application.
Custom DB Initializer: You can also create your own custom initializer, if any of the above doesn't satisfy your requirements or you want to do some other process that initializes the database using the above initializer.
Here, it can give you general idea and how to use one of these approaches.
Due to your comments CreateDatabaseIfNotExists helps you. With this approach when you add or remove your model classes, your db will be updated and your data will be stable.
Here you can find examples both Context constructor and config file
Another topic about this on stackoverflow.
I have my database already set, I want to add a new field to the model, a new column to the table, is there a way I can do this without losing all my data?
Normally if you delete the DB it will recreate everything automatically but I don't want to lose the data.
I'm using SQL Server 2008 as database.
You will need to use EF Migrations to add the new column to your database. You can read more about EF Migrations here and here.
If you're using code first, I've always just added the column to the database manually in situations like that. Unfortunately, there is no simple way to automate incremental model updates with Code First.
For example, one of EF Code First's own errors even specify manual update as the best option:
The model backing the ‘your context’ context has changed since the database was created. Either manually delete/update the database, or call Database SetInitializer with an IDatabaseInitializer instance. For example, the DropCreateDatabaseIfModelChanges strategy will automatically delete and recreate the database, and optionally seed it with new data.
I am trying to do this tutorial http://www.asp.net/mvc/tutorials/getting-started-with-aspnet-mvc3/getting-started-with-mvc3-part4-cs but instead of using the compact edition of SQL Server I am using a full install on my local machine. The way I read this tutorial is that the Entity Framework is suppose to create the tables from the objects I have defined. My problem is that I keep getting invalid object name dbo.movies, when I run the project. I finally got it to run by creating the table myself so I know the connection string and everything was correct.
My question is, is it possible to generate tables from objects created in C# and if so how?
is it possible to generate tables from objects created in C#?
Yes it is possible. Did you happen to create the Database manually in Management Studio before running the Code? That could be your problem. With Code First, the default convention is to create the database if it does not exist already. If the database already exists (even without the tables) then it is going to just use the existing database (but it won't try and create the tables).
You can either delete the database and try and run the code again to see if it will create it for you or put the following line in Global.asax:
Database.SetInitializer(new DropCreateDatabaseAlways<YourDbContextHere>());
Once it has run then I would suggest changing that line to:
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<YourDbContextHere>());
These namespaces are defined in System.Data.Entity
The DbContext class also exposes a Database property which defines the following useful methods:
Delete()
Create()
CreateIfNotExists()
So if you defined your class like so:
public class MyContext : DbContext {}
You can construct an instance like so:
MyContext db = new MyContext();
db.Database.Delete();
db.Database.Create();
ModelContext.Database.EnsureCreated();
If you create a Linq-to-Sql DataContext you can inject the structure directly into your Database whith:
DbDataContext db = new DbDataContext(connectionString);
db.CreateDatabase();
I don't know if this is kosher, but using code-first EF, when I use AddRange, EF will typically create all the tables I've defined. I wanted to keep the database because there are other tables I wanted to keep between application runs. I discovered that the tables would not be re-created after they were deleted if I did not also delete the table EF created called __MigrationHistory.
Once I deleted this table, then EF would re-create the tables without having to re-create the database.
This may not be an advisable approach in production, but for my development needs this resolved my issue. Maybe it will help someone else.
You can use FenixRepo library(also available as nuget package) to create particular table, that is a part of you Context. First of all, you should call one time, at startup static Initialize method, where first argument is a factory method, which returns instance of your Context and the second one is an instance of Configuration class. It will prepare SQL scripts for all of your tables, registered at your Context. At case of ASP.NET MVC it is a good decision to paste this code into Global.asax:
FenixRepositoryScriptExtractor.Initialize(() => new Context(), new Configuration());
Then you can create table of desired type MyTable this simple way:
var repo = new FenixRepositoryCreateTable<MyTable>();
//or repo = new FenixRepository<MyTable>();
repo.CreateTable();
Also, if your table spread between several migrations and they have nothing stuff corresponded to other tables, you can specify these migrations(i.e. names of classes from Migrations folder) via FenixAttribute, and exactly they will be used as source of SQL scripts, which will be used for table creation:
[Fenix(nameof(Initial), nameof(MyTableFirstMigration), nameof(MyTableSecondMigration))]
public class MyTable
{
//some stuff
}
Without this attribute, library will use default scripts. It is always better to specify migrations, because otherwise it is not guaranteed that all indexes will be created and also into your migrations you can include some custom code, that will not be executed at case of default solution.
Library is compatible and tested with EF 6.1.3 at case of MS SQL.