EF 6 OnModelCreating is called when I open MainWindow.xaml - c#

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?

Related

Changing connection string after moving database to App_Data folder?

I am trying to learn mvc.net. I created a small project in which I used Model first approach. The problem is I wanted my database to be shown in App_data folder for that I followed this article:
http://www.dotnetfunda.com/articles/show/2182/how-to-embed-sql-database-in-appdata-folder
In short I detached the database and then I include the database in app_data folder. Now I am facing problem in changing the connection string, Previously I generated connection string automatically using entity framework, It was like:
<add name="KeepitrememberEntities"
connectionString="metadata=res://*/EDM.csdl|res://*/EDM.ssdl|res://*/EDM.msl;
provider=System.Data.SqlClient;provider connection string="
data source=mypcname\SQLEXPRESS;initial catalog=Keepitremember;
integrated security=True;MultipleActiveResultSets=True;App=EntityFramework""
providerName="System.Data.EntityClient" />
and now I changed it to:
<add name="KeepitrememberEntities"
connectionString="Data Source=mypcname\SQLEXPRESS;
AttachDbFilename=|DataDirectory|Keepitremember.mdf;Integrated Security=True;
User Instance=True"
providerName="System.Data.SqlClient" />
When I am executing the code and trying to save the value using a form, it's showing me the error in EDM.Context.cs and error is:
An exception of type
'System.Data.Entity.Infrastructure.UnintentionalCodeFirstException'
occurred in Emptymvc.dll but was not handled in user code
Additional information: Code generated using the T4 templates for Database First
and Model First development may not work correctly if used in Code
First mode. To continue using Database First or Model First ensure
that the Entity Framework connection string is specified in the config
file of executing application. To use these classes, that were
generated from Database First or Model First, with Code First add any
additional configuration using attributes or the DbModelBuilder API
and then remove the code that throws this exception.
What I need to do now, any solution!!
Thanks for your time.
As far as I see, the first connection string is Entity Framework connection string, and the second one is SQL Express connection string. In an EF project, both of them should be exist in web.config file for DbContext and code generation template usage - hence they're not interchangeable (i.e. you should not change EF connection string into SQL Express one and vice versa).
Since you have changed EF connection string contained CSDL, SSDL & MSL information required by EF into SQL Express one, EF assumes the existing database metadata isn't exist anymore and trying to create a new database like Code First has, hence it triggers UnintentionalCodeFirstException after executing OnModelCreating method.
Instead of changing EF connection string in web.config, just add SQL Express connection string on the same connectionStrings element as this (you may need to define initial catalog name when required):
<connectionStrings>
<!-- SQL Express connection string -->
<add name="KeepitrememberConnection"
connectionString="Data Source=mypcname\SQLEXPRESS;Initial Catalog=Keepitremember;
AttachDbFilename=|DataDirectory|Keepitremember.mdf;Integrated Security=True;
User Instance=True"
providerName="System.Data.SqlClient" />
<!-- EF connection string -->
<add name="KeepitrememberEntities"
connectionString="metadata=res://*/EDM.csdl|res://*/EDM.ssdl|res://*/EDM.msl;
provider=System.Data.SqlClient;provider connection string="
data source=mypcname\SQLEXPRESS;initial catalog=Keepitremember;
integrated security=True;MultipleActiveResultSets=True App=EntityFramework""
providerName="System.Data.EntityClient" />
</connectionStrings>
NB: The connection string names should be same with predefined names in EF model generation schema.
Related issues:
Model First with DbContext, Fails to initialize new DataBase
Code generated using the T4 templates for Database First and Model First development may not work correctly if used in Code First mode
Entity Framework cant use the DbContext, model being created

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.

Code-First Migrations for multiple databases?

I have the following connection string:
<?xml version="1.0" encoding="utf-8"?>
<connectionStrings>
<add name="MyContext" connectionString="metadata=res://*;provider=System.Data.SqlClient;provider connection string='data source=SQLSERVERDB;initial catalog=TestDB_CodeFirst;user id=***;password=***;MultipleActiveResultSets=True;App=EntityFramework'" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
When I try to enable migrations I first get a warning:
Cannot determine a valid start-up project. Using project 'MyApp.Model' instead.
Your configuration file and working directory may not be set as expected.
Use the -StartUpProjectName parameter to set one explicitly.
Then I get this exception:
Argument 'xmlReader' is not valid. A minimum of one .ssdl artifact must be supplied.
Is the connection string wrong and why should I need ssdl if I'm using Code First?
NOTE
My context is in MyApp.Model project where my Migrations folder should be located.
I don't have connection strings in my main startup project because connection strings are retrieved from a second database and the user can select one of them when logging in to the application.
I have just one connection string shown above in my MyApp.Model project which points to my development database.
Also, my second question is:
If I use CF migrations, will all databases be migrated each time a user selects a different database for the first time?
EDIT
I changed the connection as mentioned below, and I get the following exception:
The item with identity 'table1' already exists in the metadata collection.
Parameter name: item
It must be noted that I reverse-engineered an existing database. So I don't know what possibly went wrong!
I've also deleted the Migrations folder and checked the database but there is no migration_history table created.
You are trying to use a connectionString designed to work with Database First / Model First. You can tell because your providerName is System.Data.EntityClient instead of System.Data.SqlClient.
Your connection string should look like this:
<connectionStrings>
<add name="MyContext"
connectionString="Data Source=SQLSERVERDB; Initial Catalog=TestDB_CodeFirst;user id=***;password=***;"
providerName="System.Data.SqlClient" />
</connectionStrings
Although I would suggest using Integrated Security instead of a user/password. Just personal preference, though.

Convert Entity Framework from Database First to Code First

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.

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.

Categories

Resources