Entity Framework Can't Find Connection String in Web.config - c#

Entity Framework doesn't seem to actually be reading connection strings from the Web.config.
I started a new project and created a context:
public class FooContext : DbContext
{
public FooContext() :
base("Foo")
{
}
// DbSets here
}
Then, I added a connection string to the projects Web.config:
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="Foo" providerName="System.Data.SqlClient" connectionString="Data Source=Foo;Initial Catalog=Foo;Integrated Security=False;User Id=foo;Password=foo;MultipleActiveResultSets=True" />
</connectionStrings>
<appSettings>
...
I enabled migrations, generated an initial migration, and then attempted to update the database. After a while, the update fails saying that it couldn't connect to the database. So I pulled my project DLL into LINQPad and ran the following:
var context = new FooContext();
context.Database.Connection.ConnectionString.Dump();
And I get the following output:
Data Source=.\SQLEXPRESS;Initial Catalog=Foo;Integrated Security=True;MultipleActiveResultSets=True
It's trying to connect to LocalDB, completely ignoring my connection string. So I tried being more explicit in the context constructor, by using "name=Foo" instead of just "Foo".
public FooContext() :
base("name=Foo")
{
}
For what it's worth, I've never had to do this before. I've even got other projects in the same solution where the I've simply passed the connection string name and they've been working fine.
I jump back over to LINQPad and run the code again, and now I get an exception:
No connection string named 'Foo' could be found in the application config file.
I'm at a complete loss. I've set up projects like this 100s of times and never had any issues. Since it may be important, I'm running the latest Entity Framework, 6.1.3. Any ideas what could possibly be going on here?

I am assuming you are running this in Visual studio, make sure you are running your web project as a startup project to use web.config. If you are running another console or .tests project as startup, it will pick up their app.config files as config file.

Please remember that EntityFramework searches connection strings in the config of the assembly which runs the code. If you for instance execute your EF methods using test methods by unit test runner then EF will search it in your tests assembly, not in the place where EF methods are stored. I believe it may be your case.
By the way - in EntityFramework 5, when Edmx is created it automatically generates DbContext it uses name=ConnectionString, not only ConnectionString, so it's I think okay.

Related

No connection string could be found in the App.config file

Visual Studio Solution:
(Project 1) I have a ASP .NET Framework API project that uses Entity Framework to access to Database.
(Project 2) Now I created NUnit project that is calling methods of project 1. Some of project1's methods are calling EF methods, so:
I added nuget package of Entity framework to project 2
I created an App.config file in project 2
But after executing test methods I get:
Test method Test.SchedulerTesting.TestMethod5 threw exception:
System.InvalidOperationException: No connection string named
'MyEntities1' could be found in the application config
file.
My app.config (project 2) content:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="MyEntities1" connectionString="provider=System.Data.SqlClient;provider connection string="data source=**********;initial catalog=******;user id=sa;password=**********;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
My Model.Context.cs (project 1) first lines:
public partial class MyEntities1: DbContext
{
public MyEntities1()
: base("name=MyEntities1")
{
}
//...
}
An app.config file applies when your production application is running. When running tests under a test runner, you need to set up a config for use with your tests. It will usually contain the same stuff as your production config.
In your case, you need a config file named something like project2.dll.config in order for the configuration to be made available to your tests. Visual Studio will not automatically rename an App.config for you because it doesn't know you want to use NUnit.
Funny thing, the first blog post I ever wrote (2005) talks about this and has many more details: http://charliepoole.org/technical/how-nunit-finds-config-files.html

Entity Framework 6: The context is being used in Code First mode with code that was generated from an EDMX file

I'm creating WPF application using Entity Framework 6 with database first approach. EF did everything for me and i'm able to connect to the database and so far downloading data works, so connection exists. But every time i add user control it gives me new error that connection string was not detected. Program works fine anyway, but its hard to program when your error window is flooded with it.
I have found out that changing context from:
public MediaRentalEntities()
: base("name=MediaRentalEntities")
{
}
To this:
public MediaRentalEntities()
: base("MediaRentalEntities")
{
}
Should fix the issue, but it doesn't.
Now it throws exception (and shows this error multiple times, based how many user controls i have, currently 3):
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
This is my current app.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
<entityFramework>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<connectionStrings>
<add name="MediaRentalEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;data source=localhost;initial catalog=MediaRental;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
It's starting to be tiring, i'm tempted to change to EntityFrameworkCore or even Dapper, it feels like EntityFramework6 is against the user, but WPF has way more functionality on .NET Framework.
in connection string replace MyModel with "MediaRentalEntities" .It will work
Or
If you have generated it using DB first then you will already have context class where code is like
public MyModel()
: base("name=MyModel")
{
}

Using web.config connection string in data access project

I'm on .NET 4.6.1, Visual Studio 2015, SQL Server Developer 2016. I want to specify my EF connection string in my main project's web.config, but I cannot for the life of me figure out how to reference that in my data access project. Every answer I can find says to do the same as in this one--that is, use this:
System.Configuration.ConfigurationManager
.ConnectionStrings["connectionStringName"].ConnectionString;
When I use that, however, the valid connection string isn't being passed. It's instead getting one that appears to be the default; the data source is being set to .\SQLEXPRESS when I have no string with that defined anywhere. Searching all files in the solution for SQLEXPRESS returns no results, so it's not hardcoded anywhere.
What is the correct way to pass my connection string from my main web.config (with the relevant transforms per build) to my data access project?
There is only one app.config / web.config that will be read from at run time and that is the config associated with the applications entry point. So if you have a web project and a referenced project that serves at the data access layer and you want to read a connection string from the config the web.config of the web project is used. The same is true for a windows application or wpf etc, only the applications main entry point's configuration will be used. Once your application is running you can reference that app.config / web.config from anywhere in your code though as you generally do this using string identifiers.
In other words if you have a project with your Data Access compiled to MyDA.dll and you app.config in that project that might be output to MyDA.dll.config (this does not happen by default) anything you have in MyDA.dll.config is ignored at runtime. The file will not be read from, only the web.config will be used OR the app.config of the .exe's entry point.
For Entity Framework's DbContext you can pass the name of the connection string directly to the constructor. You do not have to retrieve the connection string and pass it yourself. So give each connection a specific unique name in your web.config.
<connectionStrings>
<add name="ConnectionName1" connectionString="Data Source=(local);Database=YourDB;User Id=YourUser;Password=yourPassword" providerName="System.Data.SqlClient" />
<add name="ConnectionName2" connectionString="Data Source=(local);Database=YourDB2;User Id=YourUser2;Password=yourPassword2" providerName="System.Data.SqlClient" />
<!-- more here -->
</connectionStrings>
Then in your code you can create your Entity Framework's DbContext using that name.
var myEntities = new MyEntities("ConnectionName1"); // MyEntities is some class that derives from DbContext
In my past projects the DbContext I work with usually always maps to one database at run time. What I mean here is I would not use the same DbContext type multiple times pointing to different databases. In this case I hard code that name right into my DbContext type and make sure that my consuming applications have that connection name listed in the web.config or app.config respectively.
public class MyEntities : DbContext {
public MyEntities() : base("ConnectionName1") {}
}
// calling code now never has to know about the connection
using(var myEntities = new MyEntities()) { /* do something here */}
Alternatively if you really do want the complete connection element you can reference System.Configuration (add it to your project references in the project where you make the following call) and call it this way.
var connection = System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionName1"];
var conString = connection.ConnectionString; // you can also get the provider
var myEntities = new MyEntities(conString);
I have not used this approach in a while but maybe there is a good reason to use it in your case.
The data source is being set to .\SQLEXPRESS when I have no string with that defined anywhere. Searching all files in the solution for SQLEXPRESS returns no results, so it's not hardcoded anywhere.
Its hardcoded in your machine config file. Simply add:
<clear />
Above your first connection string to remove it.
You could remove the .\SQLExpress connection string from line 126 in the machine.config, however IMHO play on the safe side and dont mess with machine config, preferring to use <clear /> instead.
Have you tried connection to the Server Explorer -> Data Connections and having the property auto generated? Next thing I would tried is adding an ADO.Net data model and pointing to the correct DB with the Access driver. It may be as simple as provider on the configuration string.
Here is a simplified example and/or proper way given by MSDN:
var connectionString = ConfigurationManager.ConnectionStrings["connectionStringName"].ConnectionString;
config file like the following:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<connectionStrings>
<add name="connectionStringName" connectionString="Data Source=(LocalDB)\v11.0;Initial Catalog=DatabaseName;Integrated Security=True;Pooling=False" />
</connectionStrings>
</configuration>
Needed namespaces:
System.Configuration
From : https://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager.connectionstrings(v=vs.110).aspx
As far as I remember, when using EF, it creates a connection string that matches the name of the context you defined, so, if your context is named MyContext then you should define a connection string with that name in your app/web.config. To save you the trouble of writing the EF connection string on your own (which is much longer than a regular ADO.Net connection string), just copy the one that was generate in the DLLs .config file.
Once you have that, you can use the configuration transformation functionality built into web projects, that allows you to change portions of the .config file depending on the current build configuration, for example:
web.config - Will hold the DEVELOPMENT connection string.
web.staging.config - will hold a replace transformation with the STAGING connection string.
web.release.config - will hold a replace transformation with the RELEASE connection string.
Hope it helps!
<configuration>
<connectionStrings>
<add name="CONNECTIONSTRINGNAME" connectionString="server=.; Database=YOURDATABASENAME;Integrated Security=true;" providerName="System.Data.SqlClient"/>
</connectionStrings>
</configuration>
change the capital letters with your own data

Connection String in Unit Test App.Config is ignored: SQLExpress gets set to LocalDB

I have a load of unit tests that were running fine in Visual Studio 2013. I dont know if it is related, but I can't think of what else might have changed. I have moved my project to VS2015.
Now whenever I run my unit tests, all the tests that use a data context fail with an error indicating they are trying to use (localdb)\V11.0 and integrated security to access the database.
However, my development database is on .\sqlexpress and has a SQL login.
I've been through every config file, including the app.config in the unit test project, and they all specify the correct database. If I debug step through the code I can reach the line where the data context is created and inspect its properties and see the connection string is wrong, but I can't see where it is coming from.
Here's the relevant bit of my test project's app.config file:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="speedEntitiesDev" connectionString="metadata=res://*/mydb.csdl|res://*/mydb.ssdl|res://*/mydb.msl;provider=System.Data.SqlClient;provider connection string="Server=.\sqlexpress;Database=thedatabase;User ID=theuser;Password=thepassword;Connection Timeout=30;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient" />
</connectionStrings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
<parameters>
<parameter value="Server=.\sqlexpress;Database=thedatabase;User ID=theuser;Password=thepassword;Connection Timeout=30;MultipleActiveResultSets=True" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
When I step into the unit test this is what the property inspector says is the value of the connection string is:
"Data Source=(localdb)\\v11.0;Initial Catalog=thedatabase;Integrated Security=True"
Note that the database name is correct, but everything else is wrong.
I did previously have a database hosted locally in localdb but after upgrading my development computer I stopped using it.
UPDATE:
I've discovered that if I rename the connection in the above file, then this breaks the test in a different way. Then I get an error that the connection string is not found:
System.InvalidOperationException: No connection string named 'speedEntitiesDev' could be found in the application config file..
Other changes to the connection string also have an effect (like if I change the database name, the connection goes to the new database name, and uses the login and password I supply.)
System.Data.Entity.Core.EntityException: The underlying provider failed on Open. ---> System.Data.SqlClient.SqlException: Cannot open database "thedatabase123" requested by the login. The login failed. Login failed for user 'theuser'..
When I set the connection string back to "thedatabase" it resets to using localdb and integrated security. It's like it's got an alias going or something.
After diving through the code for a few days, I noticed that in one older library referenced by every class tested by every failing test, there was a data update written as:
dc.SubmitChanges();
and it hit me, this class was using LINQ to Sql instead of Entity Framework. Somehow the class using LINQ to Sql was altering the connection string and defaulting to (localdb) which was what we were using when that library was written.
I changed the class to use Entity Framework instead and suddenly all my tests started respecting the connection string again.
This was weird because
The old referenced library didn't actually do any data updates any more (the data update code in it was legacy and long since placed elsewhere)
The old library didn't even have a valid reference to the data class that supplied its connection string
Despite this, just referencing the old library via the unit tests caused connection string weirdness.

Running Code First Migrations manually through migrate.exe

I am currently trying to get my migrations running through command line using the migrate.exe tool.
My project structure is as follows:
MyProject.WebAPI - my API project which accesses method in
Repositories
MyProject.Repositories - project responsible for all DB work,
including where the migration files are stored, context is configured, and Configuration class is held
Migrations work fine when running the WebAPI project as the DB initializer is set up there in the Application_Start as follows:
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, MyProject.Repositories.Migrations.Configuration>());
The reason for wanting to not do this anymore, is for when I am installing the code to a machine. I am aiming to get the database initialized at install time, so need to be able to run migrations from command line. To start to do this, I have got a copy of migrate.exe in the bin directory of the WebApi project, as well as the MyProject.Repositories.dll.
I want to therefore be able to use the web.config file in the WebApi project to configure up and run the initializer. The entity framework portion of this looks as follows:
<configuration>
....
<connectionStrings>
<add name="MyConnectionString" connectionString="..." providerName="System.Data.SqlClient" />
</connectionStrings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<contexts>
<context type="Repositories.MyContext, MyProject.Repositories">
<databaseInitializer type="System.Data.Entity.MigrateDatabaseToLatestVersion`2[[Repositories.MyContext, MyProject.Repositories], [Repositories.Configuration, MyProject.Repositories]], EntityFramework">
</databaseInitializer>
</context>
</contexts>
</entityFramework>
</configuration>
And I am running migrate.exe as follows:
migrate.exe MyProject.Repositories.dll /startUpDirectory:"%current%" /connectionStringName:MyConnecitonString /startUpConfigurationFile:"%parent%\web.config"
current and parent are just variables set in a batch file.
When this set up is run, I get the following error:
ERROR: Failed to set database initializer of type 'System.Data.Entity.MigrateDatabaseToLatestVersion`2[[MyProject.CampaignManagerContext, MyProject.Repositories], [Repositories.Configuration, MyProject.Repositories]], EntityFramework'
for DbContext type 'Repositories.MyContext, MyProject.Repositories' specified in the application configuration. See inner exception for details.
Is this possible to do between two projects, or would I have to run this on the actual Repositories project itself, using its own app.config?
EDIT:
I have been working more on this, and have changed my call to migrate to just:
migrate.exe MyProject.Repositories.dll /connectionString:MyConnectionString /connectionProviderName:System.Data.SqlClient
This gives me an error of:
ERROR: Format of the initialization string does not conform to specification starting at index 0.
Looks like it is getting closer to working...

Categories