Create Entity Framework Seed method from existing database - c#

We're in the process of converting a 15-year-old application into C#/Entity Framework Code First.
I've been able to create a migration for the table structures that I'll need, and I'd like to fill them with the data from our old application. Of course, it's possible to simply create a script using Management Studio, but I'd like to leverage Code First if possible.
I see that it's possible to reverse engineer a database schema. Is there a simple way that I could generate a migration or Seed method from existing data in a database? I'm not too worried about performance - it's enough data to be a pain to recreate by hand, but neither are we talking about thousands of rows.

Entity Framework itself should not be used for mass insertion/deletion/updating of records since the performance is really poor. If you want the seeding to be part of your migrations then you could include your SqlCommands inside your Seed method:
protected override void Seed(Context context)
{
context.Database.ExecuteSqlCommand("Command Here");
}
base.Seed(context);

Related

Asp.net MVC DB First Approach - Migrations

For my past Asp.NET MVC projects I have used the Code First approach to create my web applications.
Here I got a new one, there is an old system with an already created SQL Server Database.
I need to recreate a system for the existing database.
So I have started to use Database First Approach.
I connected to the database and models & datasets generated according to the tables.
So I want to know If I want to add a column to the table which I used earlier, update it on the model, and do migration and update the database.
So I can't use it here, right?
If I want to change something, I have to change it from the database from the SQL server side, and then how I updated it on my project?
Personally, I found their database structure is somewhat wrong for certain cases.
But there are already 5000+ data on the tables and they don't wanna lose it or they have not agreed to maintain two databases for their operations.
Ideas for this matter are highly appreciated.
This is a very common scenario. Microsoft calls it Code First with Existing database. You create scaffolding that builds model out of the database. You probably want to apply constraints and generally improve referential integrity in the database and scaffold the model a few times.
Once you are happy with the model - you stop making changes in the database! You are switching to Code First approach, where you make all the changes in the code, create migrations and apply migrations to the database.
I think, Database First referred to the approach in early versions of Entity Framework that created .edmx file. I don't think this approach is even possible today. Certainly, not recommended
So what I have done here on my end using .net core and above was, that I initially created a migration before applying changes to the entities. Then after that, I removed the code inside the initial migration script. e.g.
public partial class InitialDbCreate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
}
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
so that It will not re-create the entities/tables to the existing database, and you'll not have now a problem in applying new changes to your entities.

How to check automatically that I didn't forget to add ef core code first migration

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.

How to remove the tables and migration records for an EF6 DbContext?

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.

Create SQL View With Entity Framework 6 Code First

I am new to Entity Framework 6 Code First and am trying to perform what I thought would be a simple task. I want to create a SQL View and then have an Entity in my database context that I can use to query the view.
I have tried articles such as this but the key difference in my case is that the SQL View is not an existing view coming from another existing database.
I examined the proposition made in this article but it seems like overkill to me that I would need to create some extension methods to do something as simple as create a view/entity combo and use it in my database context.
Am I missing something? I know it would be much easier if I weren't using Code First but please keep in mind it's Code First and I am trying to create a view, not reuse one from an existing database.
Colin and Kevin, Thank you for the link to your answer on the other post and your concise answer. I have used several resources to finally create a queryable entity based on a new SQL view. Just in case anyone else is new to EF 6.0 Code First and is just getting their feet wet, I do have a few steps that will hopefully benefit others in the future.
It may seem obvious to more seasoned Entity Framework developers, but in order to execute the 'Migration' approach you need to disable automatic migrations and actually dive into the guts of the Code First Migrations inner workings. Since automatic migrations is turned on out of the box, I had already created a fairly complex database with seed scripts all relying on automatic migrations and rebuilding the database on every run of my application. This post helped me wipe my migrations history and get to square 1 with automatic migrations turned off (I went with the web.config approach in case you were wondering)
After I had cleared my migrations information, I deleted the mdf from within solution explorer. That guaranteed that I wouldn't run into any problems when running Update-Database (further down the list of steps).
In the Package Manger console, I then executed Add-Migration Initial to generate an "Initial" migration. The result of this was the editable Up and Down methods as described in Colin's answer. I then followed the steps in Colin's answer by commenting out the table create statement (Entity Framework tries to create a table but we really want to create a view and map it to the Entity) and inserting my own view create sql statement at the end of the Up method. It's important to put the create statement after the creation of any tables that it may depend on. I also performed my Seed activities in the Configuration.Seed method instead of in my Context's Seed method. I see how this would be important if you were dealing with multiple migrations. Finally, as Colin suggested I added the table mapping to my context's OnModelCreating event.
The final step in this was to actually apply the migration to the database. In order to do that, in the Package Manager console you execute the Update-Database command. That statement will rebuild the database with the "Initial" migration you created and edited in earlier steps.
It still surprises me that I need to do all of this custom work to create a view and map it to an entity with Code First, but at the end of the day it was helpful in getting me started on migrations as you can only rely on the "automatic migrations" for so long anyways.
You can manually add the sql to create the view to a migration then consume it as per your first link.
The answer in the link provided by Colin does the job.
In case there are lots of views to be created, it can be a good idea to save the view queries in separate files and add them in a resource (.resx) file instead of hard-coding the sql queries in the Migration Up() method.
For e.g.
public override void Up()
{
Sql("ResourceFileName.ResourceName");
}
instead of hard coding like
{
Sql("EXEC ('CREATE View [dbo].[ClientStatistics] AS --etc");
}

Design database using ORM modeller or just Entity Framework?

As we are starting a new project I am wondering what your take is on how to create/design the database.
Options:
Use TOAD for SQl Server to create the entities and generate DDL (SQL) script
Use Entity Framework Code First approach where you start with the code
...
My problem with EF code first is that it is hard for me to keep track of changes and actually applying the EF generated migration scripts to the database. Especially in the beginning where changes are anything but rare.
How do you keep track and apply changes to the model? In other words, how do you keep your EF C# code in sync with the database?

Categories

Resources