ADO.NET Entity Connection String for Multiple Projects - entity-framework
I am using multiple layer project where the DataModel hosts the ADo.NET Entity model and DataAccess layer does the validation.
However everytime I get a error like this
The specified named connection is either not found in the configuration, not intended to be used with the EntityClient provider, or not valid.
I have tried connection strings
<add name="SalesEntities" connectionString="metadata=res://*/SalesEntities.csdl|res://*/SalesEntities.ssdl|res://*/SalesEntities.msl;provider=System.Data.SqlClient;provider connection string="Data Source=.;Initial Catalog=Phoenix;Integrated Security=True;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient" />
and
<add name="SalesEntities" connectionString="metadata=.\SalesEntities.csdl|.\SalesEntities.ssdl|.\SalesEntities.msl;provider=System.Data.SqlClient;provider connection string="Data Source=.;Initial Catalog=Phoenix;Integrated Security=True;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient" />
also tried other combinations to refer the Root Directory of the Called project directory but no luck.
Any help is highly appreciated. Many Thanks as always :).
You have to put those connection strings in each applications app.config file. If you have a DAL that you generated the model in, and then try to consume the DAL in an EXE the same thing will happen. The EXE does not know the connection string.
The easiest thing I have found is to put an app.config on each project and just copy the connection string from the DAL I generated the models in originally. Then each will have a copy of that same connection string.
If you copy your App.Config file into the main project and replace all the " with the normal ' character it should run
I suggest a slight variation on the suggestions given above.
It's not a huge improvement, but at least it gives you some separation of concerns.
When the EF wizard creates the .edmx file and its associated .Designer.cs file, the C# code declares a partial class. So you can simply add another.cs file to the project containing the two EDM files.
This new file defines an additional static function for the same namespace and class.
This new static function will return an instance of the desired type (the descendant of ObjectContext).
The new file is a separate file, so it won't be overwritten if you re-create the .edmx and .Designer.cs.
You copy and paste the connection string from the .config of the EDM project, which is kind of a hack, but at least it keeps the connection string hidden in the EDM project.
The new file looks like this:
namespace MyNamespace
{
public partial class MyEntities : ObjectContext
{
public static MyEntities New_MyEntities()
{
string connStr;
MyEntities theContext;
connStr = "metadata=res://*/MyClass.csdl|res://*/MyClass.ssdl|res://*/MyClass.msl;provider=System.Data.SqlClient;provider connection string=\"Data Source=localhost\\SQLSERVER;Initial Catalog=MyDb;Integrated Security=True;MultipleActiveResultSets=True\"";
// set the connection string
theContext = new MyEntities(connStr);
// allocate it
return theContext;
// return it
}
}
}
To get a new entities object, you simply call the static function New_MyEntities() from your calling project.
I passed the entityconnectionstring to all the instances of the objectContext classes and its working now.
But its a too much overhead, creating a property with connectionstring and passing it as a parameter to each instance
I add the same problem, trying to unit-test my DAL. I've found that this works :
<add name="SalesEntities" connectionString="metadata=res://*;provider=System.Data.SqlClient;provider connection string="Data Source=.;Initial Catalog=Phoenix;Integrated Security=True;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient" />
I had a similar problem with a WinForms project and despite trying everything I could find related to it on the web could not resolve my problem..... until I removed the field that I was using for my ObjectContext (private CubEntities _oc = new CubEntities()) from my BaseForm to the actual form using it.
I got same problem & i tried all the mentioned method. finally i solved it as mentioned. In my case I have separate data layer and presentation layer. in my app.config (data layer) i have connection like this.
<add name="LibraryMgtSysEntities" connectionString="metadata=res://*/DataLibraryMgtSys.csdl|res://*/DataLibraryMgtSys.ssdl|res://*/DataLibraryMgtSys.msl;provider=System.Data.SqlClient;provider connection string="data source=abc;initial catalog=LibraryMgtSys;Persist Security Info=True;user id=sa;password=123;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient" />
in my web.config i manually configured connection as follows:
<add name="DefaultConnection" providerName="System.Data.SqlClient"
connectionString="Data Source=abc;
Initial Catalog=LibraryMgtSys;
Integrated Security=SSPI;
user id=sa;password=123;" />
it gives me same exception as mentioned above. so i solved it by adding app.config value in web config file.
my final web.config file as follows:
<connectionStrings>
<clear />
<add name="LibraryMgtSysEntities" connectionString="metadata=res://*/DataLibraryMgtSys.csdl|res://*/DataLibraryMgtSys.ssdl|res://*/DataLibraryMgtSys.msl;provider=System.Data.SqlClient;provider connection string="data source=TILANITHOTAMUNE\SQLEXPRESS;initial catalog=LibraryMgtSys;Persist Security Info=True;user id=sa;password=testing;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient" />
<add name="DefaultConnection" providerName="System.Data.SqlClient"
connectionString="Data Source=abc;
Initial Catalog=LibraryMgtSys;
Integrated Security=SSPI;
user id=sa;password=123;" />
</connectionStrings>
I had the issue in one of my projects, as entity framework connection string was required by a job, a web application and a test project. One way to deal with this was the following:
1) Use UnitOfWork (or a similar) pattern. This allows to control data context creation and manipulate connection string
public partial class MyContext
{
#region Members
private static readonly object objSync = new object();
private static readonly string DATACONTEXT_KEY = "MyContext_UserInstance";
// TODO: read from a place accesible to all deployed projects
// remove hardcoded database
private static readonly string DefaultConnectionString = #"metadata=res://*/MyContext.csdl|res://*/MyContext.ssdl|res://*/MyContext.msl;provider=System.Data.SqlClient;provider connection string='data source=Server;initial catalog=MyDatabase;integrated security=True;multipleactiveresultsets=True;App=EntityFramework'";
private static string connectionString;
#endregion
public MyContext(String connectionString) : base(connectionString)
{
}
/// <summary>
/// Uses a UnitOfWorkStore to return the same instance of MyContext, that is unique
/// per user, per postback (or CallContext, if not in an HttpContext environment, such as unit tests or console apps)
/// </summary>
public static MyContext Instance
{
get
{
// Dirty (non thread-safe) check
if (UnitOfWorkStore.GetData(DATACONTEXT_KEY) == null)
{
lock (objSync)
{
// Thread-safe check
if (UnitOfWorkStore.GetData(DATACONTEXT_KEY) == null)
{
MyContext context = new MyContext(DefaultConnectionString);
connectionString = context.Database.Connection.ConnectionString;
UnitOfWorkStore.SetData(DATACONTEXT_KEY, context);
}
}
}
return (MyContext)UnitOfWorkStore.GetData(DATACONTEXT_KEY);
}
}
}
Data context should allow direct connection string input:
public MyContext(String connectionString) : base(connectionString)
{
}
Related
MVC4 + EntityFramework: metadata only found from within web.config - why is that?
I want to change our EF-driven database-first ASP.NET MVC4 web application in such a way that I can specify the database to connect to at runtime. For the beginning, I simply wanted to substitute the entry in the connectionStrings section of the web.config with a coded version. But first things first. Here's my web.config connection section: <connectionStrings> <add name="WEB_Entities" connectionString="metadata=~/bin/Models\WEB_Models.csdl|~/bin/Models\WEB_Models.ssdl|~/bin/Models\WEB_Models.msl;provider=System.Data.SqlClient;provider connection string="data source=testsvr;initial catalog=DEMO;persist security info=True;user id=sa;password=xxxxxxxx;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" /> </connectionStrings> When using this setting, everything runs just fine. Now I tried to comment out this entry and hard-code it, thereby moving the setting from the web.config to the global.asax.cs. I read about the EntityConnectionStringBuilder, but for the beginning I simply want to give the whole connection string as the constructor parameter of an EntityConnection: string CS = #"metadata=~/bin/Models\WEB_Models.csdl| ~/bin/Models\WEB_Models.ssdl| ~/bin/Models\WEB_Models.msl; provider=System.Data.SqlClient; provider connection string=""Data Source=testsvr\sqlexpress; Initial Catalog=DEMO; Integrated Security=True;MultipleActiveResultSets=True"""; conn = new EntityConnection(CS); conn.Open(); The conn object is a static object that lives in my application class: public static EntityConnection conn; In order to use this connection object, I changed my DBContext code to use the aforementioned connection object as constructor parameter, rather than the Name of an entry in the web.config: public partial class WEB_Entities : DbContext { public WEB_Entities() : base(PAMVCTEST.MvcApplication.conn,true) //: base("name=WEB_Entities") { } Now when I compile an run the whole thing, the connection to the db server seems to be possible (because I get some network related errors when e.g. changing the datasource to something wrong), but the application does not find the given metadata files. This is the error: The supplied connection string is not valid, because it contains insufficient mapping or metadata information. Parameter name: connection I don't understand why the metadata files cannot be found, they are definitely present in the given location. As soon as I change everything back to using the web.config connection entry, everything works as expected. I also tried changing the metadata files location to this: res://*/Models.WEB_Models.csdl|res://*/Models.WEB_Models.ssdl|res://*/Models.WEB_Models.msl I made sure that the resource names are correct with ILMerge. THe result is the same: when I use the web.config way, it works - when I set it by code, I get the same error as mentioned above. What can I do to resolve this issue? Are there any workarounds? And why in the world do we have to cope with such awful and error-prone connection strings with nested escapings and stuff? It's 2013!!! :-] Thanks for your help!
Call it from DbContext. Change your DbContext constructor to the following: public class MyDbContext : DbContext { public MyDbContext() : base("DefaultConnection") { } public MyDbContext(string conStr) : base(conStr) { } // ... } Then add your desired ConStrs to the web config. Finally, when you want another ConStr than the DefaultConnection pass its name to the DbContext() constructor: Models.MyDbContext db = new Models.MyDbContext("MyConStr");
decrypt connectionstring with entity framework
I've made a class called Crypto to encrypt en decrypt connectionStrings. This class works perfectly. The idea is to get the encrypted connectionstring in the config file: <add name="MyConnString" connectionString="KsY+XWC0GnsepTlVu0Z3BU4r0hCAfgrCl/gbqlasndFmCjq0iiTNC7r0JySqm4BtSnSktE20EfDe9F3cDZTaQqwUgmdQTrxBc8cp5HhC9G6PEyzXIVzy2HMyOIH45yTQ9j70uMPV7TUazlnvzRDYnrKJwpgHNQehjMovgkWKCfZji1kQNVN7/61yvdrv+d6KpQKU5Al5W2QKkI7wxYzvJ4vMwH6XoCk1RnulKFKvaMExWtjQTh4XOy2Wo4M9UHKM/FuhjrsxsBg4JgcUcPGfrJZortFmmeDYt7D7QP6/I9HlIrmR4K42/hKSb/ZGiDV9szK6A/V1u9p5qctqFCui7Dx0AKkvUqFIWOWQHtvivV0R/PW8+R1bxsNkr6wUK6A5uPyghJmP4Qv0VI3vW8z0Tw==" providerName="System.Data.EntityClient" /> the problem is where and how do I decrypt the connectionstring (the decrypt method works) I've tried making these adjustments to the designer class within the edmx file: public partial class KlantenBITEntities : ObjectContext { public static string DecryptedConnectionString { get { return Crypto.DecryptFromBase64String(ConfigurationManager.ConnectionStrings["MyConnString"].ToString()); } } And in the constructor I tried to pass the decrypted connectionstring : public KlantenBITEntities(): base(DecryptedConnectionString,"KlantenBITEntities") { this.ContextOptions.LazyLoadingEnabled = true; OnContextCreated(); } If I to this I get this error: Keyword not supported:'data source' I've encrypted the whole entity framework connectionstring (with csdl-,ssdl-,msl-file etc..) Could this be the cause? Any help with finding a proper way to decrypt the entity framework connectionstring is very much appreciated.
Found the answer here: KeyWord Not Supported: data source the problem was "e . Replacing it by single quotes solves it.
Entity Framework - supply a connection string to constructor
I'm using EF in my C# project. We're about to add clients which will have other databases with other connection strings. There's no need to sync between DBs. I tried using the following c'tor (the 2nd out of 3 supplied): public AppEntities(string connectionString) and I get the following error: 'Keyword not supported: 'data source'.' The connection string is as follows: metadata=res://EntityFramework/App.csdl|res://EntityFramework/App.ssdl|res://EntityFramework/App.msl;provider=System.Data.SqlClient;provider connection string="Data Source=dbname\dbname;Initial Catalog=App;Persist Security Info=True;User ID=User;Password=password;MultipleActiveResultSets=True" This is the same connection string that is used when taken from App.Config. I don't want to take it from there but rather build it myself (thus leaving the username & password hard-coded in my app's code and not in free text. Any idea? Thanks.
The connectionstring parameter is not an Entity Framework Connectionstring (as in the .config file) but it has to be a "normal" .net connectionstring. The link's example shows how to "convert" the ef connectionstring to a normal connectionstring (using the EntityConnectionStringBuilder.ToString() method). If you pass the app.config's unprepared string you will get the mentioned error. You can use the EntityConnectionStringBuilder to parse the app.config value and convert it. Hope that helps.
How to configure ProviderManifestToken for EF Code First
I have a asp.net MVC3 project using EF code-first. For my unit testing I have been using SQL Server CE 4.0 and SQL Server 2008 Express. Both have worked perfectly with EF generating my database as expected. However, when I run my application outside of a unit test and point it at my connection strings I get the error ProviderIncompatibleException: The provider did not return a ProviderManifestToken string I have read the MS documentation on this and it appears this is a SqlVersion token that the EF model generates. The problem is that I am using the code first approach so I have no .edmx file nor do I know where to point my metadata info to because the db hasn't been generated yet. I know my connection strings as far as db name, username, and pass are correct because changing them to wrong values throws the expected error. Not sure where to begin. Thanks. Here is my connection string: <connectionStrings> <add name="SqlConnection" providerName="System.Data.SqlClient" connectionString="Data Source=WORKSTATION\SQLEXPRESS;Initial Catalog=CodeFirst;Integrated Security=False; Persist Security Info=False;User ID=CodeFirst_user;Password=password1;Connect Timeout=120;MultipleActiveResultSets=True;"/> </connectionStrings>
If you're using EF 6 (just released) you have an alternative. Dependency Resolution You can use the new dependency resolution feature to register an implementation of IManifestTokenResolver (described in this preview documentation as IManifestTokenService). This article gives a bit more information on how to use DbConfiguration. The easiest way to use it is like this: DbConfigurationType(typeof(EntityFrameworkDbConfiguration))] public class MyContextContext : DbContext { } This example avoids any trip to the database when building the metadata for SQL Server connections, and automatically specifies SQL Server 2005 compatability. using System.Data.Common; using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Data.Entity.Infrastructure.DependencyResolution; using System.Data.SqlClient; /// <summary> /// A configuration class for SQL Server that specifies SQL 2005 compatability. /// </summary> internal sealed class EntityFrameworkDbConfiguration : DbConfiguration { /// <summary> /// The provider manifest token to use for SQL Server. /// </summary> private const string SqlServerManifestToken = #"2005"; /// <summary> /// Initializes a new instance of the <see cref="EntityFrameworkDbConfiguration"/> class. /// </summary> public EntityFrameworkDbConfiguration() { this.AddDependencyResolver(new SingletonDependencyResolver<IManifestTokenResolver>(new ManifestTokenService())); } /// <inheritdoc /> private sealed class ManifestTokenService : IManifestTokenResolver { /// <summary> /// The default token resolver. /// </summary> private static readonly IManifestTokenResolver DefaultManifestTokenResolver = new DefaultManifestTokenResolver(); /// <inheritdoc /> public string ResolveManifestToken(DbConnection connection) { if (connection is SqlConnection) { return SqlServerManifestToken; } return DefaultManifestTokenResolver.ResolveManifestToken(connection); } } }
After hours of searching & fiddling, I found a way to do it. Turns out the DbModelBuilder class takes a DbProviderInfo in its Build method, so I use that instead of relying on EF to call OnModelCreated: // 'Entities' is my DbContext subclass, the "container" in EF terms. public static Entities GetNewContext() { // Get a connection, for example: var connection = new SqlConnection(GetConnectionString()); // Create a DbModelBuilder var modelBuilder = new DbModelBuilder(); // Configure the model builder. // I changed my DbContext subclass - added a public version of OnModelCreated and called it ConfigureModelBuilder Entities.ConfigureModelBuilder(modelBuilder); // Here's where the magic happens. // Build the model and pass the ProviderManifestToken (I use 2005 to avoid a bug in precision of sql datetime columns when using concurrency control) var model = modelBuilder.Build(new System.Data.Entity.Infrastructure.DbProviderInfo("System.Data.SqlClient", "2005")); // Compile the model var compiledModel = model.Compile(); // Create the container (DbContext subclass). Ideally all the previous stuff should be cached. return new Entities(connection, compiledModel, true); } Obviously this needs some reorganization (e.g. cache the compiled model so you don't need to re-build it every time a context is created). For me this completely solved the problem. Enjoy!
I just had this exact problem but I traced it down to my SQL Server service wasn't running. I had just restarted my computer and usually it starts on it's own but didn't for some reason.
In my case, my connection string name must match the context class name. Connection String: <connectionStrings> <add name="NunuContext" connectionString="Data Source=|DataDirectory|Nunu.sdf" providerName="System.Data.SqlServerCe.4.0" /> </connectionStrings> Context Class: using System.Data.Entity; namespace Nunu.Models { public class NunuContext : DbContext { System.Data.Entity.DropCreateDatabaseIfModelChanges<Nunu.Models.NunuContext>()); public DbSet<Nunu.Models.NunuFirst> NunuFirsts { get; set; } public DbSet<Nunu.Models.NunuLast> NunuLasts { get; set; } } }
I found, when i provided explicit "User Id=abcUser; Password=somePwd;" in my connection string i am able to resolve the same error. Earlier i was using the "Trusted_Connection=true;", which allowed me to debug my web project, but started giving me error - {"The provider did not return a ProviderManifestToken string."} as soon as i added the Windows azure project and tried debugging the Azure project after adding my web project as a web role under it. Hope it helps some one experiencing a similar situation. Thanks, Vivek Bahl
Changing to Data Source=localhost worked for me also using MS SQL 2008 R2 Express
Changing the Data Source to localhost in the connectionString solved my problem.
I had this problem when working through the MVC3 tutorial on ASP.NET. My solution ended up being to use (localhost) instead of a named Data Source. This works fine on my box, for local dev work, but wouldn't help if the database were on a separate server.
I see some comments about oracle above, so here's the code for "EntityFrameworkDbConfiguration" adjusted for oracle: internal sealed class EntityFrameworkDbConfiguration : DbConfiguration { /// <summary> /// Initializes a new instance of the <see cref="EntityFrameworkDbConfiguration"/> class. /// </summary> public EntityFrameworkDbConfiguration() { this.AddDependencyResolver(Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices.Instance); } }
This has proven helpful for me: <connectionString="Data Source=WORKSTATION\SQLEXPRESS;Initial Catalog=CodeFirst;User ID=CodeFirst_user;Password=********"/> </connectionStrings>
How to use Settings.settings for entity framework connection strings?
I'd like to store the Entity model connection string in the app.config using the same approach used by old Typed DataSet. Both use the same section: <connectionStrings>. Entity saves the connection as: <add name="MyDB_Entities" connectionString="metadata=res://*/MyDB.csdl|res:......" providerName="System.Data.EntityClient" /> Typed DataSet saves as: <add name="MyTest.Properties.Settings.MyDbString" connectionString="Data Source=.\sqlexpress;...." providerName="System.Data.SqlClient" /> The former is only accessibile using a "not-typed" syntax, like: string s = ConfigurationManager.ConnectionStrings["MyDB_Entities"].ConnectionString; The latter is "wrapped" by Settings.settings. So you can write: string s = Settings.Default.MyDbString; The Entity entry does not contain the namespace so Settings.settings is not able to parse it. Any idea /suggestion?