Convert Entity Framework from Database First to Code First - c#

I am trying to convert an existing data model from Database First to Code First.
Background
The current solution (put in place before me) uses a Database project to define the model. This is then published to a database, and we then update an EDMX model from said database.
Finally, a couple of T4 templates are run to generate POCO classes from the EDMX model, as well as the DBContext.
I want to get rid of this, and move purely to a Code First migration approach.
What I've Done So Far
I have taken the POCO classes that were generated by the T4 template, and made them first class citizens of the project.
I then removed the T4 template from the solution
I took the DBContext that was generated by the T4 template, and also made it a first class citizen of the project.
I then removed this T4 template from the solution
From the Package Manager Console, I ran "Enable-Migrations", and it created my Migrations folder
I also changed the connection string to use the System.Data.SqlClient provider.
Was:
<add name="MyContext" connectionString="metadata=res://Project.Data/Model.MyModel.csdl|res://Project.Data/Model.MyModel.ssdl|res://Project.Data/Model.MyModel.msl;provider=System.Data.SqlClient;provider connection string="data source=MY-SERVER;initial catalog=MY-DB;integrated security=True;multipleactiveresultsets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
Changed to:
<add name="MyContext" connectionString="data source=MY-SERVER;initial catalog=MY-DB;integrated security=True;multipleactiveresultsets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
Here is where I am having an issue
I am now trying to create the initial migration, passing the -IgnoreChanges flag so that I get an empty migration (given the age of the database, I want future migrations to be based off the current schema, and not create a migration from scratch).
When I run: Add-Migration InitialCreate -IgnoreChanges
I get this error:
Unable to load the specified metadata resource.
When I run: Add-Migration InitialCreate -IgnoreChanges -ConnectionString "data source=MY-SERVER;initial catalog=MY-DB;Integrated Security=SSPI;" -ConnectionStringProviderName "System.Data.SqlClient"
I get this error:
Can not override the connection for this context with a standard
DbConnection because the original connection was an EntityConnection.
At a loss here. It appears that even though I've removed references to the EDMX model, the context still knows about it. I'd like to get rid of it completely and go pure Code First.
Any help appreciated.

Just comment out the contents of the InitialCreate.cs
then run in PM
update-database
new migrations will work correctly after that.

Ask the basic question: How many tables are in the database, and is it worth replacing a house of cards hodge-podge of build/deploy tools for another hodge-podge house of cards set of tools?
For a large 400+ table EF solution with similar custom build steps hacks, we replace it in stages with each product release.
We replaced the C# EF usage for a few tables at time with each release and eventually retired all of the third party build/deploy tools and old EF code.
Replace them in functional area chunks, with replacing usage of the tables in that functional area all at the same time.
We stopped using EF migrations as they cost more and more as time went on due to the complexity.

Related

How to generate Entity Framework Objects from script

I am working on a entity framework project generating the Entity classes using the New-> ADO.NET Entity Data Model -> Code First From Database. I then select nearly 100 tables to generate (not all tables are suitable to go in the model).
Problem is I am regularly updating the schema, and the only way to refresh the model seems to be to delete and start again, which is fine except I have to re-select the nearly 100 tables again.
Is there any easy way of scripting this generation process?
You should look into using Entity Framework Migrations and start doing your schema changes from the code itself
Set the CompanyName.ProjectName.Infrastructure.EfRepository (the project which has your DbContext) as start up project of the solution
Open the Package manager console
Choose CompanyName.ProjectName.Infrastructure.EfRepository as default project
Run the following commands:
Enable-Migrations -ConnectionStringName "EfDataRepository"
Add-Migration Initial -ConnectionStringName "EfDataRepository"
Update-Database -ConnectionStringName "EfDataRepository" -Script -SourceMigration:0
Then delete the auto-generated Migrations folder within the EF project!
Where EfDataRepository is the connection string name.

EF 6 OnModelCreating is called when I open MainWindow.xaml

I have an Entity Framework 6.1.3 application that uses Database First.
The application works and I get the data I want from the database.
The problem is that when I open (double click) MainWindow.xaml I get this error:
UnintentionalCodeFirstException: The context is being used in Code First
mode with code that was generated from an EDMX file for either Database
First or Model First development. This will not work correctly. To fix
this problem do not remove the line of code that throws this exception.
If you wish to use Database First or Model First, then make sure that
the Entity Framework connection string is included in the app.config or
web.config of the start-up project. If you are creating your own
DbConnection, then make sure that it is an EntityConnection and not some
other type of DbConnection, and that you pass it to one of the base
DbContext constructors that take a DbConnection. To learn more about
Code First, Database First, and Model First see the Entity Framework
documentation here: http://go.microsoft.com/fwlink/?LinkId=394715
So EF is calling OnModelCreating(..)
Which it shouldn't!
The connection string from app.config:
<connectionStrings>
<add name="AuthorBookEntities" connectionString="metadata=res://*/AuthorBook.csdl|res://*/AuthorBook.ssdl|res://*/AuthorBook.msl;provider=System.Data.SqlClient;provider connection string="data source=LENOVO-PC;initial catalog=BOOKS;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
All the EF code is as created by the T4 scripts.
The application is one WPF program, no dlls or anything...
What could be wrong?

Server Explorer shows both dbContext and database.mdf active

I may have just confused the implementation of the database to my ASP.NET MVC project, but I have a separate data layer with a connection string pointed to a .mdf file.
I then imported the data models through the ADO.NET Entity Data Model code-first to existing database.
When I go to enable migrations, no problem.
However, now I'm trying to Add-migration, and I get:
Unable to generate an explicit migration because the following
explicit migrations are pending: [201504081848445_InitialCreate].
I checked my server Explorer, and noticed that I have both "DatabaseContext" and a Database.mdf showing up. Sorry if this is a completely elementary question, but my suspicion is that it has something to do with my connection string? I saw that when I first enable and initially create migrations, it does show up in my DatabaseContext. But the next day, I see "databaseContext" missing the _migrationHistory, and I see the error message that the explicit migrations are pending.
My connection string:
<connectionStrings>
<add name="DatabaseContext"
connectionString="data source=(LocalDB)\v11.0;attachdbfilename=|DataDirectory|\Database.mdf;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"
providerName="System.Data.SqlClient" />
</connectionStrings>
EDIT 1
Now i'm having trouble enabling and updating the database migrations. I've re-imported the data model code-first, and re-enabled migrations.
I see that now DatabaseContext contains only the table _MigrationHistory, and nothing else. My .mdf has all the tables except for _migrationHistory.

Not using database connection string

I have google'd the crap out of this problem, I cannot find a solution.
Using EF code first approach against a domain assembly, being consumed by a .net web application.
in the domain project there is a app.config, in there I have the following connection string for EF
<connectionStrings>
<add name="DefaultConnection" connectionString="Initial Catalog=easyDayTea;Data Source=localhost;user=sa; password=12344321" providerName="System.Data.SqlClient" />
Then in the context class TeaDb.cs I have the following constructor:
public TeaDb()
: base("name=DefaultConnection")
{
}
I have also tried just using "DefaultConnection" by itself in the constructor.
The problem:
Everything was fine until EF decided it wasn't going to take notice of additional classes/tables added to the context, so I removed EF from the project by deleting the migrations folder and empting the database of tables, then re ran enable-migrations and then the web application project to make EF do it's stuff to the database. However it did nothing!
When I run the web application though it works! and there is data (from the seed) in the tables, however not in any database i can see! It must be using a portable sql file, which doesn't make sense as I have it configured for a specific database / server by use of the configuration string.
I have also tried specifically specifying the connection string to use by doing a:
update-database -ConnectionStringName DefaultConnection -f
Still no joy.
If anyone could help me it would be amazing!
Thanks,
Xavier.
You'll find your database at Users\[youruser]\[Name you passed in your context constructor].mdf
app/web.config are only used if they are in the main project, if you have an app.config/web.config outside your main project it will not be used (some templates add them, but they are meant to be used as an example).
Check this answer for a similar problem with EF4
EF doesn't use the connection string from the app.config in the class library. It will use the connection string from the web.config in your web application. If you don't have the connection string defined in your web.config then it might be using conventions to attach the database with LocalDb in your App_Data directory.

The model backing the '--Context' context has changed since the database was created - but db is new production database

I've got this error for the 762nd time but this time I am getting it as soon as I attempt to access my Production site, straight after deleting the 'production' database on Azure and then publishing my site.
The model backing the 'PropertyContext' context has changed since the database was created. Consider using Code First Migrations to update the database
I deleted the database because I couldn't fix this issue any other way but it still doesn't work.
Some important points:
I'm using EF6 and publishing to Azure.
This is 1 of 2 projects/sites that uses the same Repo project. I have no
problems with the other one, just this one.
I have tried publishing the problem project first (after deleting the db) and
second with the same result.
I have tried deleting both WEBSITES and the DB from Azure and starting again
I have tried deleting all migrations and starting with a fresh data model
I have tried the following in my Global.asax (in both projects)
Database.SetInitializer PropertyContext>(null); <-- SO won't let me put the first <
and
Database.SetInitializer(new MigrateDatabaseToLatestVersion<PropertyContext, MyConfiguration>());
new PropertyContext().Database.Initialize(true);
I'm using .net 4.5
Why am I getting this error on a new database and how can I get this site to work?
Just ran into the same error in ASP.Net application. In my case I did not use Code First, but I used standard ASP.Net authentication provider which apparently uses Code First, and authentication was broken because of this issue.
Here is quick and dirty solution is you don't care much about existing user records:
For me the solution was to drop the dbo.__MigrationHistory table, authentication started working fine after that. Be aware! This solution is not for everyone! This will fix the problem, but it is potentially risky.
If you cannot afford to lose data in AspNet* tables:
ASP.Net authentication provider automatically creates tables in your database:
AspNetRoles
AspNetUsers
AspNetUserRoles
AspNetUserClaims
AspNetUserLogings
The tables are empty by default, if you haven't created any new logins for your web site, you can use "quick and dirty" solution above. If you do care about preserving user information or just curios how Code First migrations work, follow these steps:
Open your Web.config file and check the name of the connection string you have for your database. It will be one of the records under <connectionStrings> element.
Open Package Manager Console:
Tools –> Library Package Manager –> Package Manager Console
In Package Manager Console window, use a drop-down to set Default Project. Make sure this is the project that contains ASP.Net authentication provider code.
Execute command:
Update-Database -ConnectionStringName MyConnectionStringName
Replace the MyConnectionStringName with the actual name you looked up in web.config.
As a result of this command you will see a new folder "Migrations" with a bunch of code generated by the Update-Database command. Re-build and re-deploy your app, your new migration code will be executed on startup and would bring the database schema in sync with an updated version of ASP.Net authentication provider code.
When using Code First with Migrations, your database creates a table called __MigrationHistory to track the current schema. When you run your application your Entity Framework will check this table to make sure that the database schema matches your database entities. If they do not match, you will get this error.
To update your database follow these steps:
Open the Package Manager Console (View -> Other Windows -> Package Manager Console) in Visual Studio
In the Package Manager Console Window, there is a drop down with your projects in, make sure it is set to the project that contains your DbContext
Make sure that the project that contains your App.Config / Web.Config file is "Set as Startup Project" (If you have multiple Configs, it must be the one with the Database Connection String defined.
Type Update-Database -ConnectionStringName MyConnString where MyConnString is the name (not the actual connection string) of your connection string in your App.Config / Web.Config
If you get an error like this: "Unable to update database to match the current model because there are pending changes and automatic migration is disabled."
You should enable Automatic Migrations and try again.
To enable Automatic Migrations
In the Migrations folder (in the project with your DbContext), open Configuration.cs.
Make sure the Constructor contains: AutomaticMigrationsEnabled = true;
To stop Entity Framework/DbContext from monitoring changes on your database you could simply delete the __MigrationHistory table in your database. It is then up to you to make sure that the database remains updated manually.
MSDN article here
The solution from this is to use the static method SetInitializer and bind to the context a Null value. If you are working on a Web solution, the best position to write the code is in the Application_Start of your Global.asax.cs file.
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
//...
Database.SetInitializer<MyContext>(null);
}
I got a similar problem this morning. Suddenly the error appeared and couldn't be resolved:
The model backing the 'ApplicationDbContext' context has changed since
the database was created. Consider using Code First Migrations to update
the database
I have one project for MVC and another project for the model, context and repositories. I've been working on it for weeks but today it said stop.
I have tried to delete database, enable-migration, add-migration and update-database so many times that I've lost count. I've added initializers to MigrateDatabaseToLatestVersion as well as DropCreateDatabaseIfModelChanges. All in vain...
What finally made it work was to move model, context and repositories into the MVC project (not something I was keen on)...then it worked right out of the box without any code changes at all (besides namespaces)! Very strange...
I've read so many blog posts during the day trying to solve this problem. One of them (I don't know which one) mentioned a bug in Visual Studio 2013 where reference to DLL files weren't always updated as they should, suggesting that my MVC project missed out something when I was running add-migration and update-database in my separate project. But it's just a guess.
I'm using EF 6.1 and .Net 4.5.1 in my solution.
Got a similar problem! Answer is here
http://www.asp.net/mvc/overview/older-versions/getting-started-with-aspnet-mvc3/cs/adding-a-new-field
(Rick Anderson)
There are two approaches to resolving the error:
Have the Entity Framework automatically drop and re-create the database based on the new model class schema. This approach is very convenient when doing active development on a test database, because it allows you to quickly evolve the model and database schema together. The downside, though, is that you lose existing data in the database — so you don't want to use this approach on a production database!
Explicitly modify the schema of the existing database so that it matches the model classes. The advantage of this approach is that you keep your data. You can make this change either manually or by creating a database change script.
I have spent some hours trying to solve this problem. One project was working, the other one wasn't.
I had different projects referencing different versions of Entity Framework. In my case, I had a Console app and a Windows Service app, both referencing a third project containing code first classes and DbContext.
After running Update-Package EntityFramework everything worked fine in both projects.

Categories

Resources