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

The context is being used in Code First mode with code that was generated from an EDMX file

我正在使用 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生成的Connection String是:

<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" />

然后我将实体构造函数重载为:

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

而默认构造函数是:

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

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

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 服务器中创建了数据库。但后来当我试图查询该数据库时,出现错误:

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

它会抛出一个错误

The context is being used in Code First mode with code that was generated from an EDMX file for either Database First or Model First development. This will not work correctly. To fix this problem do not remove the line of code that throws this exception. If you wish to use Database First or Model First, then make sure that the Entity Framework connection string is included in the app.config or web.config of the start-up project. If you are creating your own DbConnection, then make sure that it is an EntityConnection and not some other type of DbConnection, and that you pass it to one of the base DbContext constructors that take a DbConnection. To learn more about Code First, Database First, and Model First see the Entity Framework documentation here: http://go.microsoft.com/fwlink/?LinkId=394715

我能做什么?我必须对所有用户数据库和 ABCEntities 的相同对象使用单个 DbContext,即 "db" 以在控制器方法中访问数据库。 我已经研究过 DbFactory 方法,但发生了同样的错误。

我想做一个单实例多租户应用程序

问候。

当您使用数据库优先方法并使用 edmx 时,那么使用 OnModelCreating 就没有意义了。

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

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