MySQL Connector/NET 集成了对 Entity Framework 6 (EF6) 的支持,现在包括对 EF 6.4 版本的跨平台应用程序部署的支持。本章介绍如何配置和使用在 Connector/NET 中实现的 EF6 功能。
在这个部分:
app.config
文件中的配置部分以添加连接字符串和连接器/NET 提供程序。
<connectionStrings>
<add name="MyContext" providerName="MySql.Data.MySqlClient"
connectionString="server=localhost;port=3306;database=mycontext;uid=root;password=********"/>
</connectionStrings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework"/>
<providers>
<provider invariantName="MySql.Data.MySqlClient"
type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.EntityFramework"/>
<provider invariantName="System.Data.SqlClient"
type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer"/>
</providers>
</entityFramework>
使用以下技术之一应用程序集引用:
-
NuGet 包。
安装 NuGet 包以在安装过程中自动将此引用添加到
app.config
or
web.config
文件中。例如,要安装 Connector/NET 8.0.22 的包,请使用以下安装选项之一:
命令行界面 (CLI)
dotnet add package MySql.Data.EntityFramework -Version 8.0.22
-
包管理器控制台 (PMC)
Install-Package MySql.Data.EntityFramework -Version 8.0.22
-
带有 NuGet 包管理器的 Visual Studio。对于此选项,选择
nuget.org
作为包源,搜索
mysql.data
并安装稳定版本的
MySql.Data.EntityFramework
.
-
MySQL 安装程序或 MySQL Connector/NET MSI 文件。
安装 MySQL Connector/NET,然后将
MySql.Data.EntityFramework
程序集的引用添加到您的项目中。根据使用的 .NET Framework 版本,程序集取自
v4.0
、
v4.5
或
v4.8
文件夹。
-
MySQL 连接器/NET 源代码。
从源构建连接器/NET,然后将以下数据提供者信息插入到
app.config
or
web.config
文件中:
<system.data>
<DbProviderFactories>
<remove invariant="MySql.Data.MySqlClient" />
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL"
type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=8.0.22.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</DbProviderFactories>
</system.data>
始终更新版本号以匹配
MySql.Data.dll
程序集中的版本号。
在上下文类中
添加:
[DbConfigurationType(typeof(MySqlEFConfiguration))]
-
DbConfiguration.SetConfiguration(new
MySqlEFConfiguration())
在应用程序启动时
调用。
-
DbConfiguration
在配置文件中
设置类型:
<entityFramework codeConfigurationType="MySql.Data.Entity.MySqlEFConfiguration, MySql.Data.EntityFramework">
也可以创建自定义
DbConfiguration
类并添加所需的依赖项解析器。
Connector/NET 8.0.22 中的跨平台支持
实现了 EF 6.4 作为初始提供程序版本,以包括 Linux 和 macOS 与 Microsoft .NET Standard 2.1 的兼容性。
异步查询和保存
添加了对自 .NET 4.5 以来可用的基于任务的异步模式的支持。Connector/NET 支持的新异步方法有:
ExecuteNonQueryAsync
ExecuteScalarAsync
PrepareAsync
连接弹性/重试逻辑
支持从瞬时连接故障中自动恢复。要使用此功能,请添加到
OnCreateModel
方法中:
SetExecutionStrategy(MySqlProviderInvariantName.ProviderName, () => new MySqlExecutionStrategy());
基于代码的配置
让您可以选择在代码中执行配置,而不是像传统做法那样在配置文件中执行。
依赖解析
引入了对服务定位器的支持。一些可以用自定义实现替换的功能已经被排除在外。要添加依赖解析器,请使用:
AddDependencyResolver(new MySqlDependencyResolver());
可以添加以下解析器:
DbProviderFactory -> MySqlClientFactory
IDbConnectionFactory ->
MySqlConnectionFactory
MigrationSqlGenerator ->
MySqlMigrationSqlGenerator
DbProviderServices ->
MySqlProviderServices
IProviderInvariantName ->
MySqlProviderInvariantName
IDbProviderFactoryResolver ->
MySqlProviderFactoryResolver
IManifestTokenResolver ->
MySqlManifestTokenResolver
IDbModelCacheKey ->
MySqlModelCacheKeyFactory
IDbExecutionStrategy ->
MySqlExecutionStrategy
拦截/SQL 日志记录
提供低级构建块,用于拦截 Entity Framework 操作,并在顶部构建简单的 SQL 日志记录:
myContext.Database.Log = delegate(string message) { Console.Write(message); };
DbContext 现在可以使用已经打开的 DbConnection 创建
,这使得在创建上下文时打开连接会很有用(例如,当您无法保证连接状态时在组件之间共享连接)
[DbConfigurationType(typeof(MySqlEFConfiguration))]
class JourneyContext : DbContext
public DbSet<MyPlace> MyPlaces { get; set; }
public JourneyContext()
: base()
public JourneyContext(DbConnection existingConnection, bool contextOwnsConnection)
: base(existingConnection, contextOwnsConnection)
using (MySqlConnection conn = new MySqlConnection("<connectionString>"))
conn.Open();
using (var context = new JourneyContext(conn, false))
改进的事务支持提供对框架外部事务的支持以及在实体框架内创建事务的改进方法。从 Entity Framework 6 开始,
Database.ExecuteSqlCommand()
默认情况下会将命令包装在一个事务中(如果命令尚不存在)。此方法有重载,允许用户根据需要覆盖此行为。通过诸如此类的 API 执行模型中包含的存储过程
ObjectContext.ExecuteFunction()
。也可以将现有事务传递给上下文。
DbSet.AddRange/RemoveRange提供了一种优化的方式来从集合中添加或删除多个实体。
支持插入/更新/删除存储过程的代码优先映射:
modelBuilder.Entity<EntityType>().MapToStoredProcedures();
幂等迁移脚本
允许您生成一个 SQL 脚本,该脚本可以将任何版本的数据库升级到最新版本。为此,请
Update-Database -Script -SourceMigration:
$InitialDatabase
在程序包管理器控制台中运行命令。
可配置的迁移历史表
允许您自定义迁移历史表的定义。
// Code-Based Configuration and Dependency resolution
[DbConfigurationType(typeof(MySqlEFConfiguration))]
public class Parking : DbContext
public DbSet<Car> Cars { get; set; }
public Parking()
: base()
// Constructor to use on a DbConnection that is already opened
public Parking(DbConnection existingConnection, bool contextOwnsConnection)
: base(existingConnection, contextOwnsConnection)
protected override void OnModelCreating(DbModelBuilder modelBuilder)
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Car>().MapToStoredProcedures();
public class Car
public int CarId { get; set; }
public string Model { get; set; }
public int Year { get; set; }
public string Manufacturer { get; set; }
下面的 C# 代码示例显示了如何在将数据存储在 MySQL 表中的应用程序中使用先前模型中的实体。
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
namespace EF6
class Example
public static void ExecuteExample()
string connectionString = "server=localhost;port=3305;database=parking;uid=root";
using (MySqlConnection connection = new MySqlConnection(connectionString))
// Create database if not exists
using (Parking contextDB = new Parking(connection, false))
contextDB.Database.CreateIfNotExists();
connection.Open();
MySqlTransaction transaction = connection.BeginTransaction();
// DbConnection that is already opened
using (Parking context = new Parking(connection, false))
// Interception/SQL logging
context.Database.Log = (string message) => { Console.WriteLine(message); };
// Passing an existing transaction to the context
context.Database.UseTransaction(transaction);
// DbSet.AddRange
List<Car> cars = new List<Car>();
cars.Add(new Car { Manufacturer = "Nissan", Model = "370Z", Year = 2012 });
cars.Add(new Car { Manufacturer = "Ford", Model = "Mustang", Year = 2013 });
cars.Add(new Car { Manufacturer = "Chevrolet", Model = "Camaro", Year = 2012 });
cars.Add(new Car { Manufacturer = "Dodge", Model = "Charger", Year = 2013 });
context.Cars.AddRange(cars);
context.SaveChanges();
transaction.Commit();
catch
transaction.Rollback();
throw;