decrypt connectionstring with entity framework - 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 &quote . Replacing it by single quotes solves it.

Related

Read DbContextOptions value in Entity Framework core constructor

In my asp.net core service, I have this in the startup
services.AddDbContext<Mydb_Context>(
options => options.UseSqlServer(Configuration["Settings:ConnString"]));
and to make it works, I created also this snippet:
public Mydb_Context(DbContextOptions<Mydb_Context> options) : base(options)
{
//other stuff here
}
My problem now is: in "other stuff here" section, how can I read the options value and retrieve my connection string? Since there another dll and not the same project, I can't just read it again from the appsettings.json.
If I break my code during a debug session, I can see the connection string in the value inside this object, but I don't know how to get it properly. I see this value inside the "Extension" attribute of the options object.
So, how can I read the DbContextOptions value?
So, how can I read the DbContextOptions value?
You can (not publicly but using some EF Core internal infrastructure objects, in particular RelationalOptionsExtension class), but you don't need to.
To get the connection information, simply use context Database property and GetDbConnextion method:
public Mydb_Context(DbContextOptions<Mydb_Context> options) : base(options)
{
//other stuff here
var connectionString = this.Database.GetDbConnection().ConnectionString;
}

How to specify EntityFramework ProviderName in an Azure Function

I'm trying to port some webjob code to the new Azure Functions. So far I've managed to import my DLL's and reference them succesfully, but when I use the connection string in my code, I get an error saying I have to add the ProviderName:
The connection string 'ConnectionString' in the application's
configuration file does not contain the required providerName
attribute."
Which is normally not a problem because in a webjob (or web app), this will be in the App or Web.config, and the connectionstring will simply be overwritten with whatever I entered in Azure.
With Azure Functions, I don't have a web.config (Although I tried adding one to no avail), so naturally the providername is missing.
How do I specify that?
EDIT:
After some playing around and some helpful tips by people below, I've almost managed to get it working.
What I do now is the following:
var connString = **MY CONN STRING FROM CONFIG**; // Constring without metadata etc.
EntityConnectionStringBuilder b = new EntityConnectionStringBuilder();
b.Metadata = "res://*/Entities.MyDB.csdl|res://*/Entities.MyDB.ssdl|res://*/Entities.MyDB.msl";
b.ProviderConnectionString = connString.ConnectionString;
b.Provider = "System.Data.SqlClient";
return new MyDB(b.ConnectionString);
Which gives me what I need for calling the database. I use a static method in a partial class to get an instance of the Database which runs the above code, and I decorate my MyDB Partial with [DbConfigurationType(typeof(MyDbConfiguration))]
I define that configuration as:
public class MyDBConfiguration: DbConfiguration
{
public MyDBConfiguration()
{
SetProviderFactory("System.Data.EntityClient", EntityProviderFactory.Instance);
}
}
My problem remains when I want to actually use the EF Entities. Here, it will try to initialize the database type using the original configuration, giving me the original error once again. As per this stack trace:
at Void Initialize()
at System.Data.Entity.Internal.EntitySetTypePair GetEntitySetAndBaseTypeForType(System.Type)
at Void InitializeContext()
at System.Data.Entity.Core.Objects.ObjectContext CreateObjectContextFromConnectionModel()
at Void Initialize()
at Boolean TryInitializeFromAppConfig(System.String, System.Data.Entity.Internal.AppConfig)
at Void InitializeFromConnectionStringSetting(System.Configuration.ConnectionStringSettings)
So how do I avoid this? I guess I need a way to hook into everything and run my custom setter..
In the end, Stephen Reindel pushed me in the right direction; Code-based Configuration for Entity Framework.
[DbConfigurationType(typeof(MyDBConfiguration))]
public partial class MyDB
{
public static MyDB GetDB()
{
var connString = **MY CONN STRING FROM SOMEWHERE**; // Constring without metadata etc.
EntityConnectionStringBuilder b = new EntityConnectionStringBuilder();
b.Metadata = "res://*/Entities.MyDB.csdl|res://*/Entities.MyDB.ssdl|res://*/Entities.MyDB.msl";
b.ProviderConnectionString = connString.ConnectionString;
b.Provider = "System.Data.SqlClient";
return new MyDB(b.ConnectionString);
}
public MyDB(string connectionString) : base(connectionString)
{
}
}
With MyDbConfiguration like this:
public class MyDBConfiguration: DbConfiguration
{
public MyDBConfiguration()
{
SetProviderServices("System.Data.SqlClient", SqlProviderServices.Instance);
SetDefaultConnectionFactory(new SqlConnectionFactory());
}
}
With the above code, EF never asks for AppConfig-related config files. But remember, if you have EF entries in your config file, it will attempt to use them, so make sure they're gone.
In terms of azure functions, this means I used the Azure Functions configuration panel in azure to punch in my ConnectionString without the Metadata and providername, and then loaded that in GetDB.
Edit: As per request, here is some explanatory text of the above:
You can't add EF metadata about the connection in Azure Functions, as they do not use an app.config in which to specify it. This is not a part of the connection string, but is metadata about the connection besides the connection string that EF uses to map to a specific C# Class and SQL Provider etc. To avoid this, you hardcode it using the above example. You do that by creating a class inheriting from DBConfiguration, and you mark (with an attribute on a partial class) your EF database class with that.
This DBConfiguration contains a different kind of way to instantiate a new database object, in which this metadata is hardcoded, but the connectionstring is retrieved from your app settings in Azure. In this example I just used a static method, but I guess it could be a new constructor also.
Once you have this static method in play, you can use that to get a new database in your database code, like this:
using (var db = MyDB.GetDB()) {
// db code here.
}
This allows you to use EntityFramework without an APP.Config, and you can still change the connectionstring using Azure Functions APP settings.
Hope that helps
Using this question you can set your default factory before opening the connection by having your personal DbConfiguration class (see this link also for usage):
public class MyDbConfiguration : DbConfiguration
{
public MyDbConfiguration()
{
SetDefaultConnectionFactory(new SqlConnectionFactory());
}
}
Now you need to tell your DbContext to use the new configuration. As using web.config or app.config is no option, you may use an attribute to add the configuration:
[DbConfigurationType(typeof(MyDbConfiguration))]
public class MyContextContext : DbContext
{
}
Now using a connection string on your DbContext will use the SQL provider by default.
Provided answer is perfect and it helped me a lot but it is not dynamic as I dont want to hardcode my connectionstring. if you are working the slots in azure functions. I was looking for a solution where I can use more than 1 connection strings. Here is my alternative approach step by step for anybody else struggling with this problem.
most important thing is that we understand local.settings.json file
IS NOT FOR AZURE. it is to run your app in the local as the name is
clearly saying. So solution is nothing to do with this file.
App.Config or Web.Config doesnt work for Azure function connection strings. If you have Database Layer Library you cant overwrite connection string using any of these as you would do in Asp.Net applications.
In order to work with, you need to define your connection string on the azure portal under the Application Settings in your Azure function. There is
Connection strings. there you should copy your connection string of your DBContext. if it is edmx, it will look like as below. There is Connection type, I use it SQlAzure but I tested with Custom(somebody claimed only works with custom) works with both.
metadata=res:///Models.myDB.csdl|res:///Models.myDB.ssdl|res://*/Models.myDB.msl;provider=System.Data.SqlClient;provider
connection string='data source=[yourdbURL];initial
catalog=myDB;persist security info=True;user
id=xxxx;password=xxx;MultipleActiveResultSets=True;App=EntityFramework
After you set this up, You need to read the url in your application and provide the DBContext. DbContext implements a constructor with connection string parameter. By default constructor is without any parameter but you can extend this. if you are using POCO class, you can amend DbContext class simply. If you use Database generated Edmx classes like me, you dont want to touch the auto generated edmx class instead of you want to create partial class in the same namespace and extend this class as below.
This is auto generated DbContext
namespace myApp.Data.Models
{
public partial class myDBEntities : DbContext
{
public myDBEntities()
: base("name=myDBEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
}
this is the new partial class, you create
namespace myApp.Data.Models
{
[DbConfigurationType(typeof(myDBContextConfig))]
partial class myDBEntities
{
public myDBEntities(string connectionString) : base(connectionString)
{
}
}
public class myDBContextConfig : DbConfiguration
{
public myDBContextConfig()
{
SetProviderServices("System.Data.EntityClient",
SqlProviderServices.Instance);
SetDefaultConnectionFactory(new SqlConnectionFactory());
}
}
}
After all you can get the connection string from azure settings, in your Azure Function project with the code below and provide to your DbContext
myDBEntities is the name you gave in the azure portal for your connection string.
var connString = ConfigurationManager.ConnectionStrings["myDBEntities"].ConnectionString;
using (var dbContext = new myDBEntities(connString))
{
//TODO:
}
Adding an answer in the event you cannot simply change the way you instantiate you DbContext. This would occur if you are calling code that has DbContexts being instatiated with the parameter-less constructor.
It involves using a static constructor to read your connection string from the appsettings in the azure portal and passing it in to your DbContext base constructor. This allows you to circumvent the need for a providerName and also allows you to retain use of the portal configuration without needing to hardcode anything.
Please refer to my accepted answer here: Missing ProviderName when debugging AzureFunction as well as deploying azure function
Stumbled upon this and solved it like this, inside of the Azure Function.
public static class MyFunction
{
// Putting this in more than one place in your project will cause an exception,
// if doing it after the DbConfiguration has been loaded.
static MyFunction() =>
DbConfiguration.Loaded += (_, d) =>
d.AddDefaultResolver(new global::MySql.Data.Entity.MySqlDependencyResolver());
// The rest of your function...
//[FunctionName("MyFunction")]
//public static async Task Run() {}
}
You can access the site's App Settings by going to the portal, clicking Function app settings and then Configure app settings. That will open up a blade that allows you to set all the app settings for your function app. Just use the same key and value that you'd use for your web.config.

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");

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>

ADO.NET Entity Connection String for Multiple Projects

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)
{
}