Asp.net Mvc 使用EF6 code first 方式连接MySQL总结

最近由于服务器变更为Linux系统.MsSql for Linux什么时候出来到生产环境使用还是要很长时间的.于是考虑使用Mysql数据库,ORM使用EF.于是先踩下坑顺便记录一下,有需要的tx可以参考下.
当你考虑使用EF连接Mysql的时候肯定是已经在网上搜了一堆教程.网上教程基本都是使用控制台做演示.跟着一步步来姿势没错的话可能会正常运行,但项目中使用分层后,把数据层剥离出去,再使用code first连接瞬间蒙B了,各种奇葩问题随之而来.咋跟教程说的不一样呢...所以本文就一步步的介绍如何在分层的项目中使用EF code first连接Mysql.
ps:本文测试环境为windows 8.1+Vs2013+MySql5.7.12

一.搭建环境及安装对应组件

首先创建一个空的MVC项目后简单的再创建一个类库项目用于EF的操作以及实体的存放(这里为了演示没有创建过多的项目).最终结果如下:

然后在.Data项目中用Nuget安装EF.然后安装MySql数据驱动所需dll:

MySQL.Data.Entities.dll  //Nuget默认会带上MySQL.Data.dll

添加一个继承自DBContext的类MyDbContext.cs:

namespace EF2MySqlApp.Data
{
    public class MyDbContext:DbContext
    {
        public MyDbContext()
        {

        }

        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; }
    }
}

结构类似这样:
  

二.配置EF

接着该是配置数据库连接字符串了,现在在App.Config下添加connectionString字节,注意别写到configSections上边去了,否则进行添加Migration会报节点配置错误.

<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:
1.

在Configuration类的构造函数中加入:
SetSqlGenerator("MySql.Data.MySqlClient",new MySql.Data.Entity.MySqlMigrationSqlGenerator());

2.

给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)  

连接字符串测试没发现问题,那会不会是找不到这个连接字符串呢? N久后发现在这个控制台中使用的config文件默认是到当前启动项目下寻找config文件.

把Data项目设为启动项后再次运行报:

The underlying provider does not support the type ‘nvarchar(max)‘.

这个错误由于MySql字段不兼容string类型,在string类型字段前加注解[MaxLength(100)]即可解决(奇怪的是我用vs2015测试是不会报这个错误的..).
再次执行Update-DataBase -v 成功!
如果使用的mysql命令行:输入这些命令查看是否创建成功:

show databases;
use myappdb;
select * from bookinfoes;

用其他客户端的那就更不必多说了.  

三.遗留问题

1.不设置Data项目为启动项找不到该项目下App.Config里配置的字符串(控制台默认项目已为该项目)
   如果把连接字符串放到Web.Config里则需要在该项目里也安装ef,mysql.data... 但个人原因并不想在表现层出现ef等东西,不放又不去找App.config的配置.
这点着实疑惑了好久.每次这样设置启动项也挺麻烦的,所以可以手动指定连接字符串(亦可以写在其他地方读取过来放进去):

        public MyDbContext()
            : base("Data Source=127.0.0.1;port=3306;Initial Catalog=myappdb;uid=root;password=123456;Charset=utf8")
        {

        }

ps:如果迁移过程中出现未将对象引用到实例之类的错误多半原因就是连接字符串找不到或无效导致的,遇到这种问题先从连接字符串排查.

2.插入数据中含有中文乱码.
  这个问题网上众说纷纭,改这个配置改那个配置的.跟着改后会发现然并卵...我这里插入中文后使用Mysql控制台查看数据乱码了,使用Navicat查看却是正常的.所以这个问题还在观测中,如果各位有什么好的解决办法可以留言 :)

3.前几天有园友问了个问题,他使用MiniProfiler监控ef to mysql 监控不到sql语句.给他回复后也不知道他解决了没..
再次提示下:如果使用MiniProfiler过程中报了这个错误:

在尝试添加“Loaded”事件处理程序前,实体框架已在使用一个 DbConfiguration 实例。

检查下你的项目是否使用了EF的初始化数据配置.使用了的话需要把MiniProfilerEF6.Initialize();这句放到初始化配置之前.(我一般直接放到最前边 :) )

踩坑才刚刚开始,使用过程中肯定还会有各种问题.还会继续记录下来,给有需要的朋友提个醒.
如果看官中有老司机还望不吝赐教.  -_-!

时间: 2024-10-09 23:54:30

Asp.net Mvc 使用EF6 code first 方式连接MySQL总结的相关文章

【亲测】Asp.net Mvc5 + EF6 code first 方式连接MySQL总结

本文原文地址为:https://www.cnblogs.com/summit7ca/p/5423637.html 原文测试环境为windows 8.1+Vs2013+MySql5.7.12 本人在win10+vs2017+MySql5.7下测试通过 最近由于服务器变更为Linux系统.MsSql for Linux什么时候出来到生产环境使用还是要很长时间的.于是考虑使用Mysql数据库,ORM使用EF.于是先踩下坑顺便记录一下,有需要的tx可以参考下. 当你考虑使用EF连接Mysql的时候肯定是

Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理

这是本人第一次写,写的不好的地方还忘包含.写这个的主要原因是翔通过这个来学习下EF的CodeFirst模式,本来也想用AngularJs来玩玩的,但是自己只会普通的绑定,对指令这些不是很熟悉,所以就基本不用了.还有最主要的原因就是锻炼下自己的能力.好了其他就不多说了,下面来看下我对这个项目的整体概述吧: 目录: 目录我以后会在这边添加上去的 一.Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理 基本设计 项目中使用到的工具: Visual Studio 2013,

jmeter中通过jdbc方式连接mysql数据库的配置参考

jmeter中通过jdbc方式连接mysql数据库的配置参考: Database URL=jdbc:mysql://ip:port/dbname?useUnicode=true&characterEncoding=UTF-8 JDBC Driver class=com.mysql.jdbc.Driver jmeter中配置截图:

C++ ADO方式连接mysql数据库

对于软件开发其实说白了就是在不停地和数据打交道, 所以数据库的操作是必不可少的, 接下来介绍VC开发中利用ADO建立ODBC数据源来访问MySQL数据库. 从我接触的数据库编程方式来说, 我觉得在vc开发连接数据库是比较难的, 也是很容易出错. 在android中, 系统自带sqlite数据库,只需要使用SQLiteOpenHelper抽象类即可完成与数据库的操作. 在java中, 使用jdbc连接mysql数据库, 下载相应jar调用相应接口,传入数据库类型与用户名密码进行数据库的操作. 但是

ASP.NET MVC view与controller传值方式

1: ViewData传值方式ViewData的生命周期和View相同, 只对当前View有效.   ViewData["zd"] = dfdfd2:TempData传值方式   可以跨Action传递   TempData的数据至多只能经过一次Controller传递, 并且每个元素至多只能被访问一次,     例如一个用法为,抛出一个异常.跳转到error页面public ActionResult Index3(){      TempData["tempIndex&qu

Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理6

接下来先做角色这一板块的(增删改查),首先要新建一个Role控制器,在添加一个RoleList的视图.表格打算采用的是bootstrap的表格. using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace AuthorDesign.Web.Areas.Admin.Controllers { public class Role

Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理7

做完角色之后接下来做先做页面按钮的增加.删除.修改.这里用到的功能和角色那边是一样的.就不多说了.直接上代码. 后台控制器代码 using AuthorDesign.Web.App_Start.Common; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace AuthorDesign.Web.Areas.Admin

ASP.NET MVC 下拉框传值方式

在MVC中使用DropDownList接受从Controller传过来的值的方式: 控制器代码:  public ActionResult Index()         {             dk.bll.edu.EduBll<dk.model.edu.SetupRecord> setUpBll = new dk.bll.edu.EduBll<dk.model.edu.SetupRecord>();             List<dk.model.edu.Setu

Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理10

今天把用户的菜单显示和页面的按钮显示都做好了,下面先来个效果图 接下来说下我实现的方法: 首先我在每个方法前面都加了这个属性, /// <summary> /// 表示当前Action请求为一个具体的功能页面 /// </summary> public class AdminActionMethod : Attribute { /// <summary> /// 页面请求路径 /// </summary> public string ActionUrl {