注释
EF6 及更高版本 - 实体框架 6 中介绍了本页中讨论的功能、API 等。 如果使用早期版本,某些或全部信息不适用。
可以在配置文件(app.config/web.config)或代码中指定 Entity Framework 应用程序的配置。 后者称为基于代码的配置。
配置文件中的配置在 单独的文章中介绍。 配置文件优先于基于代码的配置。 换句话说,如果在代码和配置文件中设置了配置选项,则使用配置文件中的设置。
使用 DbConfiguration
EF6 及更高版本中的基于代码的配置是通过创建子类来实现的 System.Data.Entity.Config.DbConfiguration。 子类化 DbConfiguration时应遵循以下准则:
- 仅为应用程序创建一个
DbConfiguration类。 此类别指定整个应用程序域的设置。 - 将
DbConfiguration类置于与DbContext类相同的程序集中。 (如果要更改此内容,请参阅 “移动DbConfiguration”部分。 - 请为您的
DbConfiguration类提供一个公共的无参数构造函数。 - 通过从此构造函数中调用受保护的
DbConfiguration方法设置配置选项。
遵循这些准则后,Entity Framework(EF)可以在需要访问模型的工具和应用程序运行时自动发现和使用您的配置。
示例
派生自 DbConfiguration 的类可能如下所示:
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.SqlServer;
namespace MyNamespace
{
public class MyConfiguration : DbConfiguration
{
public MyConfiguration()
{
SetExecutionStrategy("System.Data.SqlClient", () => new SqlAzureExecutionStrategy());
SetDefaultConnectionFactory(new LocalDbConnectionFactory("mssqllocaldb"));
}
}
}
此类将 EF 设置为使用 SQL Azure 执行策略,以自动重试失败的数据库操作,并将 Local DB 用于按惯例从 Code First 创建的数据库。
移动 DbConfiguration
在某些情况下,无法将DbConfiguration类与DbContext类放在同一个程序集里。 例如,可能存在两个DbContext类,每个类位于不同的程序集中。 有两个选项可用于处理此问题。
第一个选项是使用配置文件来指定实例DbConfiguration 。 为此,请设置 entityFramework 节的 codeConfigurationType 属性。 例如:
<entityFramework codeConfigurationType="MyNamespace.MyDbConfiguration, MyAssembly">
...Your EF config...
</entityFramework>
codeConfigurationType 的值必须是 DbConfiguration 类的程序集和命名空间限定名称。
第二个选项是在上下文类上放置 DbConfigurationTypeAttribute 。 例如:
[DbConfigurationType(typeof(MyDbConfiguration))]
public class MyContextContext : DbContext
{
}
传递给属性的值可以是类型 DbConfiguration (如上所示)或程序集和命名空间限定的类型名称字符串。 例如:
[DbConfigurationType("MyNamespace.MyDbConfiguration, MyAssembly")]
public class MyContextContext : DbContext
{
}
显式设置DbConfiguration
在某些情况下,在使用任何 DbContext 类型之前可能需要配置。 此示例包括:
- 使用
DbModelBuilder在没有上下文的情况下构建模型 - 在应用程序上下文使用之前,使用其他框架/实用工具代码,该代码中的上下文被使用的地方< c0 />
在这种情况下,EF 无法自动发现配置,必须改为执行以下操作之一:
- 在配置文件中设置
DbConfiguration类型,如上面的移动DbConfiguration部分所述 - 在应用程序启动期间调用静态
DbConfiguration.SetConfiguration 方法
重载 DbConfiguration
在某些情况下,需要覆盖配置设置 DbConfiguration。 这通常不是由应用程序开发人员完成的,而是由不能使用派生 DbConfiguration 类的第三方提供程序和插件完成的。
为此,EntityFramework 允许注册事件处理程序,该事件处理程序可以在锁定之前修改现有配置。 它还提供一种糖方法,专门用于替换 EF 服务定位器返回的任何服务。 这是其用途:
- 在应用启动时(在使用 EF 之前),插件或提供程序应为此事件注册事件处理程序方法。 (请注意,在应用程序使用 EF 之前必须发生这种情况。
- 事件处理程序针对需要替换的每个服务调用 ReplaceService。
例如,为了替换 IDbConnectionFactory 和 DbProviderService,您可以注册一个类似这样的处理程序:
DbConfiguration.Loaded += (_, a) =>
{
a.ReplaceService<DbProviderServices>((s, k) => new MyProviderServices(s));
a.ReplaceService<IDbConnectionFactory>((s, k) => new MyConnectionFactory(s));
};
在上面的代码中, MyProviderServices 并 MyConnectionFactory 表示服务的实现。
还可以添加其他依赖项处理程序来获得相同的效果。
请注意,您也可以这样包装DbProviderFactory,但这样做只会影响EF,而不会影响EF外部的DbProviderFactory的使用。 因此,你可能希望像以前一样继续封装 DbProviderFactory 。
您还应该记住那些在应用程序外部运行的服务,例如从包管理器控制台运行迁移的服务。 当你从控制台运行迁移时,它会尝试查找你的 DbConfiguration。 但是,它是否会获取包装的服务取决于它注册的事件处理程序的位置。 如果它作为 DbConfiguration 构建的一部分被注册,那么代码应执行,并且服务应被封装。 通常情况并非如此,这意味着工具不会获取包装的服务。