本主题讲述实体框架如何发现要使用哪个数据库连接,以及您如何更改此行为。本主题同时涵盖了使用 Code First 和 EF 设计器创建的模型。
实体框架应用程序通常使用派生自 DbContext 的类。此派生类将对基类 DbContext 调用某一构造函数以控制:
- 上下文如何连接到数据库,即如何查找/使用连接字符串
- 上下文将使用 Code First 计算模型还是加载使用 EF 设计器创建的模型
- 其他高级选项
以下几个代码片段显示了一些可使用 DbContext 构造函数的方式。
在 Code First 模式下按约定使用连接
如果您还没有在应用程序中进行任何其他配置,则对 DbContext 调用无参数构造函数将会导致 DbContext 使用按约定创建的数据库连接在 Code First 模式下运行。例如:
- namespace Demo.EF
- {
- public class BloggingContext : DbContext
- {
- public BloggingContext()
- // C# will call base class parameterless constructor by default
- {
- }
- }
- }
在此示例中,DbContext 使用派生上下文类 Demo.EF.BloggingContext 的命名空间限定名称作为数据库名称,并使用 SQL Express 或 LocalDb 为此数据库创建连接字符串。如果同时安装了这两个数据库,将使用 SQL Express。
默认情况下,Visual Studio 2010 包含 SQL Express,Visual Studio 2012 包含 LocalDb。安装期间,EntityFramework NuGet 包会检查哪个数据库服务器可用。随后 NuGet 包将设置按约定创建连接时 Code First 所使用的默认数据库服务器,以此更新配置文件。如果 SQL Express 正在运行,将使用它。如果 SQL Express 不可用,则 LocalDb 将注册为默认数据库。如果配置文件已包含默认连接工厂设置,则不会更改该文件。
在 Code First 模式下按约定和指定数据库名称使用连接
如果您尚未在应用程序中进行任何其他配置,在通过要使用的数据库名称对 DbContext 调用字符串构造函数时,将会导致 DbContext 使用按约定创建的与该名称数据库的连接在 Code First 模式下运行。例如:
- public class BloggingContext : DbContext
- {
- public BloggingContext()
- : base("BloggingDatabase")
- {
- }
- }
在此示例中,DbContext 使用“BloggingDatabase”作为数据库名称,并使用 SQL Express(随 Visual Studio 2010 安装)或 LocalDb(随 Visual Studio 2012 安装)为此数据库创建连接字符串。如果同时安装了这两个数据库,将使用 SQL Express。
在 Code First 模式下使用 app.config/web.config 文件中的连接字符串
可以选择将连接字符串放入 app.config 或 web.config 文件中。例如:
- <configuration>
- <connectionStrings>
- <add name="BloggingCompactDatabase"
- providerName="System.Data.SqlServerCe.4.0"
- connectionString="Data Source=Blogging.sdf"/>
- </connectionStrings>
- </configuration>
这是一种指示 DbContext 使用数据库服务器而非 SQL Express 或 LocalDb 的简单方法 — 上例指定了 SQL Server Compact Edition 数据库。
如 果连接字符串的名称与上下文的名称(带或不带命名空间限定)相同,则使用无参数构造函数时 DbContext 会找到该连接字符串。如果连接字符串名称与上下文名称不同,则可通过将连接字符串名称传递给 DbContext 构造函数,指示 DbContext 在 Code First 模式下使用此连接。例如:
- public class BloggingContext : DbContext
- {
- public BloggingContext()
- : base("BloggingCompactDatabase")
- {
- }
- }
或者,也可以对传递给 DbContext 构造函数的字符串使用 “name=<连接字符串名称>”格式。例如:
- public class BloggingContext : DbContext
- {
- public BloggingContext()
- : base("name=BloggingCompactDatabase")
- {
- }
- }
使用此形式可以明确要求在配置文件中查找连接字符串。如果未找到具有给定名称的连接字符串,则将引发异常。
Database/Model First 使用 app.config/web.config 文件中的连接字符串
使用 EF 设计器创建的模型不同于 Code First,因为该模型事先已存在,而不是在应用程序运行时从代码生成的。该模型通常在项目中以 EDMX 文件形式存在。
Designer 会将 EF 连接字符串添加到 app.config 或 web.config 文件中。此连接字符串十分特殊,因为它说明了如何在 EDMX 文件中查找信息。例如:
- <configuration>
- <connectionStrings>
- <add name="Northwind_Entities"
- connectionString="metadata=res://*/Northwind.csdl|
- res://*/Northwind.ssdl|
- res://*/Northwind.msl;
- provider=System.Data.SqlClient;
- provider connection string=
- "Data Source=.\sqlexpress;
- Initial Catalog=Northwind;
- Integrated Security=True;
- MultipleActiveResultSets=True""
- providerName="System.Data.EntityClient"/>
- </connectionStrings>
- </configuration>
EF 设计器还将生成一些代码,指示 DbContext 通过将连接字符串名称传递给 DbContext 构造函数来使用此连接。例如:
- public class NorthwindContext : DbContext
- {
- public NorthwindContext()
- : base("name=Northwind_Entities")
- {
- }
- }
由于连接字符串是包含待用模型详细信息的 EF 连接字符串,因此 EF DbContext 十分清楚要加载现有模型(而不是使用 Code First 从代码计算模型)。
其他 DbContext 构造函数选项
DbContext 类包含支持其他一些更高级方案的其他构造函数和使用模式。其中一些选项有:
- 可 以使用 DbModelBuilder 类构建 Code First 模型,而不实例化 DbContext 实例。这样会生成 DbModel 对象。随后,在准备好创建 DbContext 实例时,可以将此 DbModel 对象传递给某一 DbContext 构造函数。
- 可 以将完整连接字符串传递给 DbContext,而不仅仅传递数据库或连接字符串名称。此连接字符串默认用于 System.Data.SqlClient 提供程序;可以通过在 context.Database.DefaultConnectionFactory 上设置不同的 IConnectionFactory 实现来更改此行为。
- 可以通过将现有 DbConnection 对象传递给 DbContext 构造函数来使用该对象。如果连接对象是 EntityConnection 的实例,则将使用连接中指定的模型,而不使用 Code First 计算模型。如果该对象是其他某一类型(例如 SqlConnection)的实例,则上下文将在 Code First 模式下使用该对象。
- 可以通过将现有 ObjectContext 传递给 DbContext 构造函数,创建包装现有上下文的 DbContext。对于使用 ObjectContext 但希望在其中一部分利用 DbContext 的现有应用程序,这一点十分有用。
浙公网安备 33010602011771号