Reputation: 2828
In my WPF app (database-first EF) I need to provide a way to the user to update / modify the database connection string (azure located) at runtime. I am extending the autogenerated partial class of MyContext
by adding the following method. However I get an error
A method of same signature already exists
What is the correct procedure of adding dynamically connection string?
Thx
Error message:
Type 'MyServDataCollection.Models.MyContext' already defines a member called 'MyContext' with the same parameter types
MyContext
class
using System.Data.Entity;
using System.Data.Entity.Core.EntityClient;
public partial class MyContext : DbContext
{
public MyContext() : base(GetConnectionString())
{
}
private static string GetConnectionString()
{
var model = "MyServDataCollectionModel";
var providerConnectionString = "metadata=res://*/Models.MyServDataCollectionModel.csdl|res://*/Models.MyServDataCollectionModel.ssdl|res://*/Models.MyServDataCollectionModel.msl;provider=System.Data.SqlClient;provider connection string="data source=xxx.database.windows.net;initial catalog=xxxx;persist security info=True;user id=xxxxxxx;password=xxxxx;MultipleActiveResultSets=True;App=EntityFramework"";
var efConnection = new EntityConnectionStringBuilder();
efConnection.Provider = "System.Data.SqlClient";
efConnection.ProviderConnectionString = providerConnectionString;
// based on whether you choose to supply the app.config connection string to the constructor
efConnection.Metadata = string.Format("res://*/Model.{0}.csdl|res://*/Model.{0}.ssdl|res://*/Model.{0}.msl", model);
// Make sure the "res://*/..." matches what's already in your config file.
return efConnection.ToString();
}
Upvotes: 0
Views: 515
Reputation: 827
If you wanted to allow consuming code to continue using a parameterless constructor to create instances of your DBContext, you could amend the T4 template to ensure the auto generated class does not define a parameterless constructor:
Remove the following from the MyContext.Context.tt file:
public <#=code.Escape(container)#>()
: base("name=<#=container.Name#>")
{
<#
if (!loader.IsLazyLoadingEnabled(container))
{
#>
this.Configuration.LazyLoadingEnabled = false;
<#
}
foreach (var entitySet in container.BaseEntitySets.OfType<EntitySet>())
{
// Note: the DbSet members are defined below such that the getter and
// setter always have the same accessibility as the DbSet definition
if (Accessibility.ForReadOnlyProperty(entitySet) != "public")
{
#>
<#=codeStringGenerator.DbSetInitializer(entitySet)#>
<#
}
}
#>
}
This will allow your partial class to work as you expect.
Upvotes: 1
Reputation: 296
This error message is correct. Parameterless constructor is already contained in generated partial class(generated by Visual Studio). To connect using customized connection string you simply call constructor with connection string(or configuration key - see help). I think this constructor is already generated but if is not, then you can simply create it adding this code to your partial class:
public partial class MyContext : DbContext
{
public MyContext(string connectionStringOrKey)
: base(connectionStringOrKey)
{
}
}
Method GetConnectionString() you can create as is only with public instead private.
Then simply call
MyContext myCtx = new MyContext(MyConnection.GetConnectionString())
for example. Another solution would be to modify your partial class with add static method CreateMyContext:
public partial class MyContext : DbContext
{
private static string GetConnectionString()
{
}
public static MyConnection CreateMyContext()
{
return new MyContext(MyContext.GetConnectionString());
}
}
In this case, but would probably be better to put these methods to another class(extension class ?).
Upvotes: 1