本主题讲述实体框架如何发现要使用哪个数据库连接,以及您如何更改此行为。本主题同时涵盖了使用 Code First 和 EF 设计器创建的模型。

实体框架应用程序通常使用派生自 DbContext 的类。此派生类将对基类 DbContext 调用某一构造函数以控制:

  • 上下文如何连接到数据库,即如何查找/使用连接字符串
  • 上下文将使用 Code First 计算模型还是加载使用 EF 设计器创建的模型
  • 其他高级选项

以下几个代码片段显示了一些可使用 DbContext 构造函数的方式。

 

在 Code First 模式下按约定使用连接

如果您还没有在应用程序中进行任何其他配置,则对 DbContext 调用无参数构造函数将会导致 DbContext 使用按约定创建的数据库连接在 Code First 模式下运行。例如:

  1. namespace Demo.EF
  2. {
  3.     public class BloggingContext : DbContext
  4.     {
  5.         public BloggingContext()
  6.         // C# will call base class parameterless constructor by default
  7.         {
  8.         }
  9.     }
  10. }

在此示例中,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 模式下运行。例如:

  1. public class BloggingContext : DbContext
  2. {
  3.     public BloggingContext()
  4.         : base("BloggingDatabase")
  5.     {
  6.     }
  7. }

在此示例中,DbContext 使用“BloggingDatabase”作为数据库名称,并使用 SQL Express(随 Visual Studio 2010 安装)或 LocalDb(随 Visual Studio 2012 安装)为此数据库创建连接字符串。如果同时安装了这两个数据库,将使用 SQL Express。

 

在 Code First 模式下使用 app.config/web.config 文件中的连接字符串

可以选择将连接字符串放入 app.config 或 web.config 文件中。例如:

  1. <configuration>
  2.   <connectionStrings>
  3.     <add name="BloggingCompactDatabase"
  4.          providerName="System.Data.SqlServerCe.4.0"
  5.          connectionString="Data Source=Blogging.sdf"/>
  6.   </connectionStrings>
  7. </configuration>

这是一种指示 DbContext 使用数据库服务器而非 SQL Express 或 LocalDb 的简单方法 — 上例指定了 SQL Server Compact Edition 数据库。

如 果连接字符串的名称与上下文的名称(带或不带命名空间限定)相同,则使用无参数构造函数时 DbContext 会找到该连接字符串。如果连接字符串名称与上下文名称不同,则可通过将连接字符串名称传递给 DbContext 构造函数,指示 DbContext 在 Code First 模式下使用此连接。例如:

  1. public class BloggingContext : DbContext
  2. {
  3.     public BloggingContext()
  4.         : base("BloggingCompactDatabase")
  5.     {
  6.     }
  7. }

或者,也可以对传递给 DbContext 构造函数的字符串使用 “name=<连接字符串名称>”格式。例如:

  1. public class BloggingContext : DbContext
  2. {
  3.     public BloggingContext()
  4.         : base("name=BloggingCompactDatabase")
  5.     {
  6.     }
  7. }

使用此形式可以明确要求在配置文件中查找连接字符串。如果未找到具有给定名称的连接字符串,则将引发异常。

 

Database/Model First 使用 app.config/web.config 文件中的连接字符串

使用 EF 设计器创建的模型不同于 Code First,因为该模型事先已存在,而不是在应用程序运行时从代码生成的。该模型通常在项目中以 EDMX 文件形式存在。

Designer 会将 EF 连接字符串添加到 app.config 或 web.config 文件中。此连接字符串十分特殊,因为它说明了如何在 EDMX 文件中查找信息。例如:

  1. <configuration> 
  2.   <connectionStrings> 
  3.     <add name="Northwind_Entities" 
  4.          connectionString="metadata=res://*/Northwind.csdl| 
  5.                                     res://*/Northwind.ssdl| 
  6.                                     res://*/Northwind.msl; 
  7.                            provider=System.Data.SqlClient; 
  8.                            provider connection string
  9.                                &quot;Data Source=.\sqlexpress; 
  10.                                      Initial Catalog=Northwind; 
  11.                                      Integrated Security=True; 
  12.                                      MultipleActiveResultSets=True&quot;" 
  13.          providerName="System.Data.EntityClient"/> 
  14.   </connectionStrings> 
  15. </configuration>

EF 设计器还将生成一些代码,指示 DbContext 通过将连接字符串名称传递给 DbContext 构造函数来使用此连接。例如:

  1. public class NorthwindContext : DbContext
  2. {
  3.     public NorthwindContext()
  4.         : base("name=Northwind_Entities")
  5.     {
  6.     }
  7. }

由于连接字符串是包含待用模型详细信息的 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 的现有应用程序,这一点十分有用。
posted on 2013-11-14 16:11  杨锐  阅读(152)  评论(0)    收藏  举报