上下文正在Code First模式中使用,其代码是从EDMX文件生成的

时间:2015-10-01 11:21:52

标签: c# asp.net-mvc entity-framework ef-code-first ef-database-first

我正在开发一个使用EF 6数据库第一种方法的MVC 5应用程序。现在我希望我的DbContext基于不同的用户访问多个数据库。就此而言,我在Web.Config文件中生成了一个连接字符串:

string str = u.Users.Where(x => x.UserName == HttpContext.User.Identity.Name).First().ConnStr;
var configuration = WebConfigurationManager.OpenWebConfiguration("~");
var section = (ConnectionStringsSection)configuration.GetSection("connectionStrings");          
ConnectionStringSettings c = new ConnectionStringSettings();    
c.ConnectionString = str;
c.Name = u.Users.Where(x => x.ConnStr == str).First().DbName;
c.ProviderName = "System.Data.SqlClient";
section.ConnectionStrings.Add(c);
configuration.Save();

配置文件中生成的连接字符串为:

<add name="Awais123" connectionString="Data Source=.;Initial Catalog=Awais123;integrated security=True;MultipleActiveResultSets=True"
      providerName="System.Data.SqlClient" />

我制作EDMX时由EF生成的连接字符串是:

<add name="ABCEntities" connectionString="metadata=res://*/Models.awais.csdl|res://*/Models.awais.ssdl|res://*/Models.awais.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=.;initial catalog=Awais;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;"
      providerName="System.Data.EntityClient" />

然后我将我的Entities构造函数重载为:

public ABCEntities(string nameorConnString) : base(nameorConnString) {}

默认的构造函数是:

public ABCEntities() : base("name=ABCEntities") {}

现在我在另一个.cs文件中声明另一个DbContext类,以生成数据库:

public partial class NewDbGen : DbContext
{
     public NewDbGen(string nameorConnString): base(nameorConnString)
     { Database.Create(); }
}

我将DbContext对象称为:

private static string str = u.Users.Where(x => x.UserName == HttpContext.User.Identity.Name).First().ConnStr;
private NewDbGen de = new NewDbGen(str); // for creating a new database
private ABCEntities db = new AbcEntities(str); // my original Entites.. and all my controllers use these entites for all queries

现在所有这些都成功运行,并且在SQL Server中创建了数据库。但后来当我尝试查询该数据库时出现错误:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
     throw new UnintentionalCodeFirstException();
}

它会抛出错误

  

上下文正在Code First模式中使用,代码是   从EDMX文件生成的数据库优先或模型优先   发展。这将无法正常工作。要解决这个问题,请不要   删除抛出此异常的代码行。如果你想使用   数据库优先或模型优先,然后确保实体   框架连接字符串包含在app.config或中   启动项目的web.config。如果你正在创建自己的   DbConnection,然后确保它是EntityConnection而不是   一些其他类型的DbConnection,并将它传递给其中一个   采用DbConnection的基础DbContext构造函数。了解更多   关于Code First,Database First和Model First,请参阅实体   这里的框架文档:   http://go.microsoft.com/fwlink/?LinkId=394715

我该怎么办?我必须对所有用户数据库和ABCEntities的相同对象使用单个DbContext,即“db”来访问控制器方法中的数据库。 我已经研究过this question DbFactory方法,但发生了同样的错误。

我想制作单实例多租户应用

的问候。

1 个答案:

答案 0 :(得分:7)

当您使用Database-First方法并使用edmx时,使用OnModelCreating毫无意义。

要拥有一个使用每个租户策略数据库的单实例应用程序,您应该:

  • 为所有租户使用单个dbcontext类
  • 向接受connnectionstring
  • 的dbcontext构造函数添加重载
  • 为每个租户创建一个数据库
  • 根据您的租户检测策略在运行时创建连接字符串
  • 根据您的租户检测策略创建dbcontext实例,传递您在运行时创建的连接字符串