I've a solution with different projects. I'm using EF6 in my 'DALProject' structured with a repository pattern. What I need to do is to make CRUD operations from another project called 'MainProject' that references the one above, but I receive this error: `
No connection string named 'MyEntity' could be found in the application config file
To resolve this my idea is to pass directly the connection string to the DBContext constructor.
So I copied in an external file the connection string that is in the App.Config of my DALProject, and then I'm going to read this file from the MainProject. This is the connection string:
metadata=res://*/My_Model.csdl|res://*/My_Model.ssdl|res://*/My_Model.msl;provider=System.Data.SqlClient;provider connection string="data source=192.xxx.xxx.xxx\SQL2008R2EXP;initial catalog=My_Catalog;persist security info=True;user id=sa;password=xxxxxx;multipleactiveresultsets=True;application name=EntityFramework"
When this is done I try to set the DBContext in this way:
public class My_Entities : DBContext{
public My_Entities(string connStr)
: base (connStr){}
}
But what I got is this error: `
No Entity Framework provider found for the ADO.NET provider with invariant name 'System.Data.SqlClient'. Make sure the provider is registered in the 'entityFramework' section of the application config file. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.`
Any helps?
Hi i am trying to create the tables using code first approach on EF5. I have created a database called "DEV_Database" on a server called "SERVER01".
After I enter "enable-migrations -contexttypename Entities -force" on package manager console I get this error "Unable to load the specified metadata resource."
I had this connection String auto generated for me by VS12, which words fine with other approaches.
Can anyone help me with this. My connection string is below.
<add name="Entities" connectionString="metadata=res://*/Models.Model1.csdl|res://*/Models.Model1.ssdl|res://*/Models.Model1.msl;provider=System.Data.SqlClient;provider connection string="data source=SERVER01;initial catalog=DEV_Database;persist security info=True;user id=USER1;password=pass;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient"/>
First, this is related to another question here on SO:
I've read and debugged my issue with the following SO article & blog:
MetadataException: Unable to load the specified metadata resource
and
http://blogs.teamb.com/craigstuntz/2010/08/13/38628/
BUT...I'm still having questions beyond just this 'fix'
I have a WebAPI (2.1), the connection string in my WebAPI is as so:
<connectionStrings>
<add name="ProjectEntities" connectionString="
metadata=res://*/ProjectModel.csdl|
res://*/ProjectModel.ssdl|
res://*/ProjectModel.msl;
provider=System.Data.SqlClient;
provider connection string="
data source=192.168.0.1;
initial catalog=Project;
persist security info=True;
user id=***;
password=***;
multipleactiveresultsets=True;
App=EntityFramework""
providerName="System.Data.EntityClient" />
When I call ToList() on a DbSet in my WebAPI (pseudo code):
DbContext _DbContext = new ProjectEntities();
DbSet<TEntity> _dbSet = _DbContext.Set<TEntity>();
_dbSet.ToList();
It works great!
When I call the same from within a WINDOWS SERVICE, I get the following error:
The app.config entry for the connection string is exactly the same as the web.config:
<connectionStrings>
<add name="ProjectEntities" connectionString="
metadata=res://*/ProjectModel.csdl|
res://*/ProjectModel.ssdl|
res://*/ProjectModel.msl;
provider=System.Data.SqlClient;
provider connection string="
data source=192.168.0.1;
initial catalog=Project;
persist security info=True;
user id=***;
password=***;
multipleactiveresultsets=True;
App=EntityFramework""
providerName="System.Data.EntityClient" />
Now, the blog shows to reference the dll manually as so:
<connectionStrings>
<add name="ProjectEntities" connectionString="
metadata=res://Project.Data.dll/ProjectModel.csdl|
res://Project.Data.dll/ProjectModel.ssdl|
res://Project.Data.dll/ProjectModel.msl;
provider=System.Data.SqlClient;
provider connection string="
data source=192.168.0.1;
initial catalog=Project;
persist security info=True;
user id=***;
password=***;
multipleactiveresultsets=True;
App=EntityFramework""
providerName="System.Data.EntityClient" />
</connectionStrings>
This does NOT work/fix the issue
The only way I've been able to fix it, is to use the fully qualified name:
<connectionStrings>
<add name="ProjectEntities" connectionString="
metadata=res://Project.Data, Version=1.6.0.0, Culture=neutral, PublicKeyToken=null/ProjectModel.csdl|
res://Project.Data, Version=1.6.0.0, Culture=neutral, PublicKeyToken=null/ProjectModel.ssdl|
res://Project.Data, Version=1.6.0.0, Culture=neutral, PublicKeyToken=null/ProjectModel.msl;
provider=System.Data.SqlClient;
provider connection string="
data source=192.168.250.125\sqlexpress;
initial catalog=Project;
persist security info=True;
user id=***;
password=***;
multipleactiveresultsets=True;
App=EntityFramework""
providerName="System.Data.EntityClient" />
</connectionStrings>
Why does this work like this? Why would this work in a web project, but not a windows service project?? I recently changed from EF5 to EF6, and this error has popped up - all this code worked previous to upgrading EF. Does anyone have any insight as to why and how/if I can just use * for the dll name in my connection string?
I thought it was an issue of where the service .exe was running and a file wasn't copied locally, but nope, the Project.Data.dll is there and it's the right version.
I used FusionLog to try and find the error, and no luck there. I'm pretty confused.
Why this happens?
The issue you are having is just a result of extra security measures to prevent binary planting or DLL hi-jacking attack (read more) when running your application as as windows service.
Why should I care?
As you probably know, there is a specific, well documented order in what every referenced DLL file is looked up. Usually it starts to search DLL in current application directory and then goes away to more "public" locations like PATH folders, GAC, etc.
Main idea of binary planting is to plant malicious DLL file in a folder which is checked before folder of the legit DLL. Loading such malicious DLL would allow attacker to gain control over the system.
Usually windows services run under elevated account (LocalSystem, LocalService, NetworkService, etc) therefore windows services are good target for binary planting attacks.
What can I do?
Microsoft have taken extra precaution steps to reduce security risks and there is a good reason for that. But you can try to work around you issues.
1) Current directory is not what you expect
Windows service starts in system folder (usually something like C:\Windows\System32)
Good news are that it is very easy to fix. You just have to change current directory on services startup.
System.IO.Directory.SetCurrentDirectory(System.AppDomain.CurrentDomain.BaseDirectory);
See blog post from Phil Haack;
2) Read documentation thoroughtly
According to EF documentation, wildcard character has special meaning and it limits places where runtime will look for DLL files:
If you specify a wildcard (*) for assemblyFullName, the Entity
Framework runtime will search for resources in the following
locations, in this order:
1) The calling assembly.
2) The referenced assemblies.
3) The assemblies in the bin directory of an application.
As your working folder is set to system folder and you references probably are not there, EF might end up looking in wrong places and your assemblies containing resources might not be loaded.
3) Stay safe with fully qualified assembly names
Although I am not completely sure about this and haven't tested, but Microsoft just might have disallowed Windows services to load DLL without providing fully qualified assembly name to reduce risk of injecting malicious DLL files;
Good read on securing your Windows services here (specially chapter 5).
4) Debug it!
EF6 happens to be open source project. This means that you can get full source of it and debug it. You can find project on CodePlex here.
Copy the dll containing ProjectEntities to different path and then reference the same in your service project.
I'm afraid I wasn't able to reproduce the error that you received, or answer why you needed to change the metadata.
That said, I did learn that, for the EF connection string, the Windows Service required a different provider connection string than the WebApi did.
The following are the steps to reproduce your error. The only difference is that I'm using localdb not SQLExpress.
The resultant code from my steps-to-reproduce is online at GitHub here: https://github.com/bigfont/EntityFrameworkWindowsServiceWebApi.
Here are those steps:
Create Web API Project
Create ASP.NET Web API 2 Empty Project (MyWebApi)
With NuGet, Install-Package EntityFramework -ProjectName MyWebApi
Add a new ADO.NET Entity Data Model called MyProjectModel.
Add an Entity called Entity1.
Generate the database from the model, calling it MyProject and using localdb.
Run the db creation script on (localdb)\v11.0
Add a new WebApi Controller named ValuesController with a Get method that queries the database.
Test by running in Visual Studio and going to localhost:123456/api/get
See: https://msdn.microsoft.com/en-us/data/jj205424.aspx
Create Windows Service Project
Create Windows Service (MyWindowsService)
Use NuGet, Install-Package EntityFramework -ProjectName MyWindowsService
Add a new ADO.NET Entity Data Model called MyProjectModel.
Add an Entity called Entity1.
Generate the database from the model, calling it MyService, using localdb.
Run the db creation script on (localdb)\v11.0
Add to the OnStart method some code that queries the database.
Add NT AUTHORITY\SYSTEM as a localdb Login and as a MyService db User.
Test by installing, starting, and writing to file:
PowerShell Installation, Startup, and Uninstall
Release> installutil .\MyWindowsService.exe
Release> Start-Service MyService
Release> installutil .\MyWindowsService.exe /u
localdb connection string in the Windows Service
In the connection string for the Windows Service, I wasn't able to use (localdb)\v11.0. Instead, I needed to use the named pipe. I found the named pipe with this command line:
> SqlLocalDB.exe info v11.0
Name: v11.0
Version: 11.0.2100.60
Shared name:
Owner: MY_COMPUTER\Shaun.Luttin
Auto-create: Yes
State: Running
Last start time: 2015-04-09 5:54:34 PM
Instance pipe name: np:\\.\pipe\LOCALDB#1010101\tsql\query
The resultant connection string, using the Instance pipe name, looked like this.
<connectionStrings>
<add name="MyProjectModelContainer"
connectionString="
metadata=
res://*/MyProjectModel.csdl|
res://*/MyProjectModel.ssdl|
res://*/MyProjectModel.msl;
provider=System.Data.SqlClient;
provider connection string="
data source=np:\\.\pipe\LOCALDB#4BCE6D95\tsql\query;
initial catalog=MyService;
Integrated Security=True;
MultipleActiveResultSets=True;
App=EntityFramework""
providerName="System.Data.EntityClient" />
</connectionStrings>
Whereas the WebApi connection string looked like this:
<add name="MyProjectModelContainer"
connectionString="
metadata=
res://*/MyProjectModel.csdl|
res://*/MyProjectModel.ssdl|
res://*/MyProjectModel.msl;
provider=System.Data.SqlClient;
provider connection string="
data source=(localdb)\v11.0;
initial catalog=MyProject;
integrated security=True;
MultipleActiveResultSets=True;
App=EntityFramework""
providerName="System.Data.EntityClient" />
</connectionStrings>
See also: http://www.connectionstrings.com/sql-server-2012/
Needing to use a different connection string with a Windows Service that we do with a WebApi project is a similar problem to what you found. From Sql Server Management Studio, from Visual Studio, and from the WebApi, we can connect by calling the data source (localdb)\v.11 whereas from a Web Service we need to call it by it's instance named pipe.
Here's a suspicion: It might be that there are multiple instance of localdb on the computer, and that we needed to absolutely specify which one we want to use. Unfortunately, this doesn't help answer why you needed to change the metadata.
This is a similar though different problem than what you faced, because you needed to change the Entity Framework metadata whereas I needed to change the provider connection string. Coincidence?
Please follow the steps bellow:
1.Write click on edmx file and then click open with of the related entity.
2.Select xml editor and click open.
3.Scroll from top to bottom of the .edmx xml file and look for any error marks.
4.If you mind errors then fix that.
5.Rebuild the solution and if no errors found then congratulations :)
I have Persistence class library, which contains my DbContext class. It also contains app.config file, where I have predefined connection string like this:
<connectionStrings>
<add name="<Namespace1>.Persistence.AssessmentContext" connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\AssessmentContext.mdf;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
Assuming that AssesmentContext has Namespace1.Persistence namespace.
When I try to enable-migrations using PM console, it gives me such an error:
An error occurred accessing the database. This usually means that the connection to the database failed. Check that the connection string is correct and that the appropriate DbContext constructor is being used to specify it or find it in the application's config file.
When I tried to debug it and put debug output into AssessmentContext ctor I found that the connection string is still using .\SQLEXPRESS data source.
Data Source=.\SQLEXPRESS;Initial Catalog=<Namespace1>.Persistence.AssessmentContext;Integrated Security=True;MultipleActiveResultSets=True
So what I am doing wrong? And why EF doesn't take my connection string from app.config?
The above connection string entry must be copied to the app.config of the executable program if you are using desktop app or copied to web.config if you are using web app.
I have a library project that accesses the database configured in app.config
I have a web project that accesses the database configured in web.config
Both are working properly
Now I want to use the library from the web project.
In Visual Studio works fine.
In production server the web project access the database but the library not is capable of accessing the database from the project web.
The ConnectionString in app.config and web.config are identical.
In production server should not take the web.config settings?
Thanks and sorry for my English
EDIT
web.config and app.config connectionStrings
<connectionStrings>
<add name="IntranetConnectionString"
connectionString="Data Source=(local)\SQLExpress;Initial Catalog=Intranet;Integrated Security=True;"
providerName="System.Data.SqlClient" />
<add name="Database.Properties.Settings.IntranetConnectionString"
connectionString="Data Source=(local)\SQLEXPRESS;Initial Catalog=Intranet;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
Error:
A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified)
If I understand correctly, try copying local the reference of the libraries, to do this, right-click the reference in your project, then, in the properties, set True to Copy Local, now you will have the libraries locally in your server.
This should work if the problem is related to the references of the libraries, it won't help if it's a web.config/app.config problem
The DLL generally takes the app.config of the host application that is calling it and not its own config. Is there some meat here?
The solution:
In the DLL create a class to access the DataTable with a constructor that receives the ConnectionString
public TestBLL(String ConnectionString)
{
TestTableAdapter ta = new TestTableAdapter();
ta.Connection = new System.Data.SqlClient.SqlConnection(ConnectionString);
}
In the Web project:
String cs = System.Configuration.ConfigurationManager.ConnectionStrings["IntranetConnectionString"].ToString();
TestBLL taBLL = new TestBLL(cs);
In taBLL have the methods to access each Query