这可能是因为尽管意图是使用“数据库优先”工作流,但实际上应用程序正在使用“代码优先”进行映射。让我解释一下,因为这可能会令人困惑。 :-)
在使用 EF Designer 和 Visual Studio 中的 DbContext 模板以进行“数据库优先”操作时,会发生三件非常重要的事情。首先,新的 Entity Data Model 向导会向您的应用添加一个连接字符串,其中包含“数据库优先”模型(即 EDMX)的详细信息,以便在运行应用程序时可以找到此模型。连接字符串的格式如下:
<connectionStrings>
<add name="MyEntities"
connectionString="metadata=res://*/MyModel.csdl|res://*/MyModel.ssdl|res://*/MyModel.msl;provider=System.Data.SqlClient;provider connection string="data source=.\sqlexpress;initial catalog=MyEntities;integrated security=True;multipleactiveresultsets=True;App=EntityFramework""
providerName="System.Data.EntityClient" />
</connectionStrings>
其次,生成的上下文类会调用基类DbContext构造函数,并指定该连接字符串的名称:
public MyEntities()
: base("name=MyEntities")
{
}
这告诉DbContext在配置中找到并使用"MyEntities"连接字符串。使用"name="意味着如果DbContext没有找到连接字符串,它会抛出异常--它不会只是按照惯例创建一个连接。
如果您想使用Database First,则必须使用生成的连接字符串。具体而言,它必须包含模型数据(来自EDMX的csdl、msl、ssdl),并且您必须确保DbContext能够找到它。在更改对基础构造函数的调用时要非常小心。
第三件事是在生成的上下文中覆盖OnModelCreating并使其抛出异常:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
这样做是因为 OnModelCreating 仅在使用 Code First 时调用。因为 OnModelCreating 主要是用于创建模型,而当使用 Database First 时,模型已经存在--运行时不需要创建任何内容。所以如果调用了 OnModelCreating,则可能是因为您无意中开始使用 Code First,通常是由于更改连接字符串或调用基类构造函数引起的。
现在,您可能想使用 Code First 映射到现有数据库。这是一种很好的模式,并得到完全支持(请参见http://blogs.msdn.com/b/adonet/archive/2011/03/07/when-is-code-first-not-code-first.aspx),但是您需要确保设置正确的映射才能使其工作。如果映射没有正确设置,则会出现本问题中的异常。