本文原文地址为:https://www.cnblogs.com/summit7ca/p/5423637.htmlhtml
原文测试环境为windows 8.1+Vs2013+MySql5.7.12mysql
本人在win10+vs2017+MySql5.7下测试经过web
最近因为服务器变动为Linux系统.MsSql for Linux何时出来到生产环境使用仍是要很长时间的.因而考虑使用Mysql数据库,ORM使用EF.因而先踩下坑顺便记录一下,有须要的tx能够参考下.sql
当你考虑使用EF链接Mysql的时候确定是已经在网上搜了一堆教程.网上教程基本都是使用控制台作演示.跟着一步步来姿式没错的话可能会正常运行,但项目中使用分层后,把数据层剥离出去,再使用code first链接瞬间蒙B了,各类奇葩问题随之而来.咋跟教程说的不同呢...因此本文就一步步的介绍如何在分层的项目中使用EF code first链接Mysql.
ps:本文测试环境为windows 8.1+Vs2013+MySql5.7.12数据库
首先建立一个空的MVC项目后简单的再建立一个类库项目用于EF的操做以及实体的存放(这里为了演示没有建立过多的项目).最终结果以下:windows
而后在.Data项目中用Nuget安装EF.而后安装MySql数据驱动所需dll:服务器
MySQL.Data.Entities.dll //Nuget默认会带上MySQL.Data.dll
本人是在Data项目中,先安装最新版的EntityFramework(版本号:6.2)网络
而后再安装:MySql.Data.Entity.EF6(安装后的名称为MySql.Data.Entity.EF6,此项会自动安装MySql.Data)app
在启动项目中没有安装这两项,也是经过了测试的ide
添加一个继承自DBContext的类MyDbContext.cs:
namespace EF2MySqlApp.Data { public class MyDbContext:DbContext { public MyDbContext() { } public DbSet<BookInfo> BookInfoes { get; set; } } }
此处,本人修改成
public class MyDbContext : DbContext { public MyDbContext():base("name=MyDbContext") { } protected override void OnModelCreating(DbModelBuilder mb) { base.OnModelCreating(mb); } public DbSet<BookInfo> BookInfoes { get; set; } }
接着建个文件夹放实体类BookInfo.cs:
namespace EF2MySqlApp.Data { public class BookInfo { public int Id { get; set; } public string Number { get; set; } public string Name { get; set; } public string Author { get; set; } public decimal Price { get; set; } public bool Deleted { get; set; } public DateTime CreatedOn { get; set; } } }
结构相似这样:
接着该是配置数据库链接字符串了,如今在App.Config下添加connectionString字节,注意别写到configSections上边去了,不然进行添加Migration会报节点配置错误.
本人是将此内容加到启动项目的web.config中的。
<connectionStrings> <add name="MyDbContext" connectionString="Data Source=localhost;port=3306;Initial Catalog=myappdb;uid=root;password=123456;Charset=utf8" providerName="MySql.Data.MySqlClient" /> </connectionStrings>
而后打开程序包管理器控制台(-_-不知道的请自定搜索),默认项目选择.Data项目,而后输入这个命令:
Enable-Migrations //启用迁移
本人测试中,此部会报”未将对象引用设置到对象的实例“的错误:
不用管它,接着下一步。
没有错误提示接着输入:
Add-Migration record1 //给本次迁移记录起个名字 这个名字能够随便起,尽可能别重名 注意这里的Migration没有s结尾.
这时看到项目下已经多了几个文件:
Configuration.cs为进行迁移前的配置文件.以时间戳+刚才输入的名字的文件为迁移记录文件.本文重点不在此,因此各个做用在此不作过多介绍.有兴趣可自行搜索学习.
在Configuration类的构造函数中有这么一句话,它的做用在因而否启用自动迁移,默认不启用:
AutomaticMigrationsEnabled=false;
在Seed方法中能够添加种子数据,迁移成功后将会执行这个方法,把数据插入到数据库中.
protected override void Seed(EF2MySqlApp.Data.MyDbContext context) { context.BookInfoes.AddOrUpdate(x => x.Id, new BookInfo { Name="C#大法好",Author="summit", Number="1234",Price=1024} ); context.SaveChanges(); }
注意最后须要保存一下
这个时候若是直接update-database将会报Sql Server链接失败的错误:以下:
在与 SQL Server 创建链接时出现与网络相关的或特定于实例的错误。未找到或没法访问服务器。....
问题来了,想链接MySql怎么默认使用了Sql Server呢.这是EF默认链接的是SqlServer 因此要告诉EF咱们须要使用Mysql:
在Configuration类的构造函数中加入:
SetSqlGenerator("MySql.Data.MySqlClient",new MySql.Data.Entity.MySqlMigrationSqlGenerator());
给MyDbcontext类增长DbConfigurationType特性:
[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))] public class MyDbContext:DbContext { public MyDbContext() { } public DbSet<BookInfo> BookInfoes { get; set; } }
ps:这个也能够在config文件里配置,我的比较喜欢用代码控制.
再次运行Update-Database -v 依然报错,但提示字符串格式不正确,往上翻翻看到DbContenniton获取字符串的时候出错了,因而猜想是不是链接字符串的问题:
System.ArgumentException: 从索引 0 处开始,初始化字符串的格式不符合规范。 在 System.Data.Common.DbConnectionOptions.GetKeyValuePair(String connectionString, Int32 currentPosition, StringBuilder buffer, Boolean useOdbcRules, String& keyname, String& keyvalue)
此处,由于本人将扎链接字符串写到启动项目的web.config的缘由,测试时未报错。
链接字符串测试没发现问题,那会不会是找不到这个链接字符串呢? N久后发如今这个控制台中使用的config文件默认是到当前启动项目下寻找config文件.
把Data项目设为启动项后再次运行报:
The underlying provider does not support the type 'nvarchar(max)'.
这个错误因为MySql字段不兼容string类型,在string类型字段前加注解[MaxLength(100)]便可解决(奇怪的是我用vs2015测试是不会报这个错误的..).
此处,本人测试时未报错。多是VS2017有所改进的缘由。所以,并未在string类型字段前加注解[MaxLength(100)]。
再次执行Update-DataBase -v 成功!
若是使用的mysql命令行:输入这些命令查看是否建立成功:
show databases; use myappdb; select * from bookinfoes;
用其余客户端的那就更没必要多说了.
另可能出现的错误问题:
Error A.出现这个错误请先检查链接字符串是否正确,mysql与mssql的链接字符串有所区别.确认无误后检查此链接是否有效,是否可正常打开.
System.Data.Entity.Core.ProviderIncompatibleException: 提供程序未返回 ProviderManifestToken 字符串。
---> MySql.Data.MySqlClient.MySqlException: Unable to connect to any of the specified MySQL hosts.
Error B.出现MySqlException此类问题可能是未安装Connector/Net驱动 可到官网下载 https://dev.mysql.com/downloads/connector/net/
此步,在VS2017中不须要。
未解析成员“MySql.Data.MySqlClient.MySqlException,MySql.Data, Version=6.9.9.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d”的类型。