动态连接字符串的设置实体框架

use*_*192 23 c# entity-framework

我正在开发一个应用程序,它将在多个数据库中使用相同的数据库模式.出于这个原因,我创建了一个名为的数据库MyTemplate.创建新用户时,他们将拥有自己的数据库实例.因此,MyTemplate_[UserName]将创建一个名为like的数据库.当用户登录时,我需要将他们的查询指向他们的数据库.出于这个原因,我知道我需要在运行时设置连接字符串.我的问题是,我也想使用实体框架.

目前,我使用MyTemplate作为源创建了一个新的.edmx.我以为我能够更新代码并在那里设置连接字符串.不幸的是,我无法弄清楚如何设置它.TemplateEntities的构造函数没有允许我传入连接字符串的重载.我注意到TemplateEntities派生自DbContext,我不认为这会是问题所在.

string connectionString = GetUsersConnectionString();
using (TemplateEntities entities = new TemplateEntities())
{
  TemplateEntity entity = new TemplateEntity();

  // Save to the database
  entities.TemplateEntity.Add(entity);
  entities.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

我创建.edmx错了吗?或者我完全错过了什么?我谷歌的所有内容都显示了一个重载,应该允许传入连接字符串.但是,我没有可用的超载.

Nic*_*ler 38

生成的TemplateEntities类标记为partial.

您所要做的就是使用部分类定义的另一部分添加另一个文件,该部分公开了您要使用的构造函数:

partial class TemplateEntities
{
  public TemplateEntities( string nameOrConnectionString )
    : base( nameOrConnectionString )
  {
  }
}
Run Code Online (Sandbox Code Playgroud)

然后将您的连接字符串传递给此构造函数.

您希望将此代码放在不同的文件中,以便在更新edmx模型时不会覆盖该代码.

  • 使用新构造函数的部分类定义必须与生成的类位于同一名称空间中 - 否则它将声明一个新类(默认情况下派生自`object`) (3认同)
  • 当我这样做时,我收到一个错误,上面写着:'object'不包含带有1个参数的构造函数.我究竟做错了什么? (2认同)

Mar*_*uer 16

尼古拉斯巴特勒的回答非常正确.除了他所说的,我还面临着为实体框架获取现有连接字符串并将其指向具有相同结构的不同数据库的问题.我使用以下代码仅更改现有字符串的数据源:

var originalConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["CSName"].ConnectionString;
var ecsBuilder = new EntityConnectionStringBuilder(originalConnectionString);
var sqlCsBuilder = new SqlConnectionStringBuilder(ecsBuilder.ProviderConnectionString)
{
    DataSource = "newDBHost"
};
var providerConnectionString = sqlCsBuilder.ToString();
ecsBuilder.ProviderConnectionString = providerConnectionString;

string contextConnectionString = ecsBuilder.ToString();
using (var db = new SMSContext(contextConnectionString))
{
    ...
}
Run Code Online (Sandbox Code Playgroud)