EF6(CodeFirst)+Mysql开发脱坑指南

废话

话说当年,在一个春光明媚的晌午,邂逅了迷人的丁香姑娘,从此拜倒在了她的石榴裙下,至今不能自拔,这位丁香姑娘就是ORM思想。

所谓ORM思想,我的理解就是根据一定的规则,把程序中的对象数据库中的关系数据相互映射转换。在当年之前,我用ADO.NET编写数据持久层,拼接T-Sql语句,这是一个相当繁琐的过程,而且针对不同的数据库,还要调整T-Sql语句。记得,第一个网站上线的时候,数据库改成了MySql的,为了适配MySql,我改了两天的Sql语句。现在每每想起,都不禁摇头哂笑。

ORM思想如何做到屏蔽各大数据库之间的差异呢?程序对象和关系数据之间的相互映射是基于一定的规则的,只要制定好规则,它们的转换就易如反掌。那么,规则怎么制定,谁来指定?规则制定可以简单理解为翻译,即把程序设计语言翻译成数据库语言(T-Sql), 无论什么数据库都兼容最基本的T-Sql语法,不过各自都有一些差异。这样不同的程序设计语言就可以针对不同的数据库开发对应的规则。通常数据库厂商或者团队或者社区都会维护这些规则,当然也可以自己DIY。

实现了ORM思想的框架也是琳琅满目,例如:

EntityFramework:.Net程序员最熟悉的啦,由Microsoft支持。

Hibernate:很流行,各种版本的都有。

Dapper:最清凉的,好像就几百K。

And so on……

CodeFirst+MySql使用姿势

如题,本教程是使用EntityFramework6框架的感悟描述(爬坑泪水),以飨同道。

自从学会了EF的基本使用,都是在别人开发好了项目框架上做CRUD,很多细节没有体会到,这次正好有个机会亲自搭建项目框架,深入体会个中奥妙。

配置:win10+vs2015community+.NetFramework4.5.2+MySql5.6

一、基本操作
1、创建控制台项目:CodeFirstDemo。

2、通过NuGet包管理器安装:EntityFramework6.1.3、MySql.Data.Entity6.9.8
检查项目的引用中是否有下图所示的四个引用

添加新建项→ADO.NET实体对象模型(命名MyContext)→空CodeFirst模型。该模型会自动在app.config中添加连接字符串:

<connectionStrings>
    <add name="MyContext" connectionString="data source=(LocalDb)\MSSQLLocalDB;initial catalog=CodeFirstDemo.MyContext;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
</connectionStrings>

很显然这是默认的MSSqlServer的配置,稍后再来修改。

3、在MyContext中,反注释掉MyEntities极其实现类代码。

public virtual DbSet<MyEntity> MyEntities { get; set; }
public class MyEntity
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

这就是程序中的对象。

根据CodeFirst的约定:Id会被设置为主键。

更多约定详见msdn(https://msdn.microsoft.com/zh-cn/data/jj679962)。

4、如何把MyEntities映射到MySql数据库中?。 三步走:

打开vs工具

第一步: 在控制台中输入Enable-Migrations(启动迁移)。注意:默认项目一定要是模型所在的项目。

此时项目中会自动生成Migration文件夹

下面我来解释下Configuration.cs类

这是迁移的配置类,在最后执行迁移的时候会执行这个类。

它有两个方法:

a、Congifuration():无参的构造方法。可以在这里配置迁移之前的操作,后文再详细描述。

b、Send(MyContext):void:这个方法是在执行迁移成功之后执行,一般用来初始化数据库用的。例如:我要在生成数据库的时候就初始化一个MyEntities记录。

protected override void Seed(CodeFirstDemo.MyContext context)
        {
            //  This method will be called after migrating to the latest version.

            //  You can use the DbSet<T>.AddOrUpdate() helper extension method
            //  to avoid creating duplicate seed data. E.g.
            //
            //    context.People.AddOrUpdate(
            //      p => p.FullName,
            //      new Person { FullName = "Andrew Peters" },
            //      new Person { FullName = "Brice Lambson" },
            //      new Person { FullName = "Rowan Miller" }
            //    );
            //
            context.MyEntities.AddOrUpdate(new MyEntity()
            {
                Name = "张三"
            });
            context.SaveChanges();
        }

第二步:在控制台输入:Add-Migration InitModel。(InitModel:为本次迁移起个名字)

此时在项目的Migration文件夹中会自动生成迁移记录文件,文件名以当前时间_本次迁移的名字作为类名。

记录文件有一个设计类和一个资源类和一个迁移具体操作的方法。

设计类:本次迁移的具体记录。自动生成、维护。

资源类:默认架构和目标。自动生成、维护。

具体操作:该类维护Up()和Down()两个方法,分别用于升级和降级。有时候需要我们自己定制,因此要理解它,可以参考我写的注释。

public partial class InitModel : DbMigration
    {
        /// <summary>
        /// 本次迁移执行的具体操作,即升级数据库。
        /// </summary>
        public override void Up()
        {
            //创建架构为"dbo",表名为”MyEntities"的数据库表。
            CreateTable(
                "dbo.MyEntities",
                c => new
                    {
                        Id = c.Int(nullable: false, identity: true),//Id,int类型,不可为空,标识列(自动增长)。
                        Name = c.String(),//Name,string类型
                    })
                .PrimaryKey(t => t.Id);//设置主键为Id

        }
        /// <summary>
        /// 以后如果回滚数据库,那么会执行此降级方法。
        /// </summary>
        public override void Down()
        {
            DropTable("dbo.MyEntities");//删除架构为"dbo",表名为”MyEntities"的数据库表。
        }
    }

第三步:在控制台输入Update-DataBase –script。生成Sql脚本。(在迁移过程中经常奇葩问题的时候,就生成sql脚本检查一下吧。)

CREATE TABLE [dbo].[MyEntities] (
    [Id] [int] NOT NULL IDENTITY,
    [Name] [nvarchar](max),
    CONSTRAINT [PK_dbo.MyEntities] PRIMARY KEY ([Id])
)
CREATE TABLE [dbo].[__MigrationHistory] (
    [MigrationId] [nvarchar](150) NOT NULL,
    [ContextKey] [nvarchar](300) NOT NULL,
    [Model] [varbinary](max) NOT NULL,
    [ProductVersion] [nvarchar](32) NOT NULL,
    CONSTRAINT [PK_dbo.__MigrationHistory] PRIMARY KEY ([MigrationId], [ContextKey])
)
INSERT [dbo].[__MigrationHistory]([MigrationId], [ContextKey], [Model], [ProductVersion])
VALUES (N‘201601021118458_InitModel‘, N‘CodeFirstDemo.Migrations.Configuration‘,  0x1F8B0800000000000400CD57DB6E1B37107D0FD07F20F8D400B6E8CB4B6AAC12B8B25D18896C23EBE49DDA1DC94479D9925C43FB6D79C827F5173AD4DE7725457683A2102068676786670EE70CA9BFBF7D8F3EAC9524CF609D307A4A4F272794804E4C2AF46A4A73BF3C7E473FBCFFE54D749DAA35F95AFB9D073F8CD46E4A9FBCCF2E1873C91328EE264A24D638B3F493C428C653C3CE4E4E7E63A7A70C3005C55C84449F73ED8582CD033ECE8C4E20F3399773938274951DDFC49BACE48E2B70194F604A67E87123ACF357A00C259752700411835C52C2B5369E7B8478F1C541ECADD1AB384303978F4506E8B7E4D24105FDA2753FB48A93B350056B03EB5449EEBC512F4C787A5ED1C286E1AF229736B42171D748B02F42D51BF2A6745E94264A868B5DCCA40D8E036E2775C411E9D98F9A36C06E091F7C9F4B9F5B986AC8BDE5F2883CE40B29928F503C9A3F414F752E65171DE2C3773D039A1EACC9C0FAE2332C2BCCB72925AC1FC786814D5827A6ACE656FBF3334AEE7071BE90D06C7EA7F2D81B0B7F8006CB3DA40FDC7BB03AE4808A2BB677ADF05DAF86DD869AA164CED79F40AFFC1352CED794DC8835A4B5A542F0450B941806799B437F9188B53B37DE4F148AE702E1369B1A2CB0F65B761515506DACAB16EAD752668CC1F71B4480A3A4C5504A6BD276CF36B00DAC56B8AC546EAD70B643E2D19C6719F2D6917C652171A5F7E3F8E56A50650E96B82DA268D0362B6117F0150CDE76E5C03D5FF0B073B3548DDCDA4DD84170BDCE88E7A1025ADAEB90F0BB0CDBAECD618A96BF1B2C49611B6FAA83064B67108C4237F3964B6EB7486A6664AEF42E59EE8B2E45D28D2F2DE30C111B601FF2C346040D86C390F27DBD3A7469566F7A76D09B51D5272F39A3AAC6295D28416A9E451A9A262E9C0735090E93F82F399302EB6D1DE65C8B25385FCE4F8A7DFD6E70D6FD7FCE1DE65C2A0F3C7CFEF3434004567F38E64767C4E1735F3F739B3C71FBABE2EBB7DD4CFF76B68FA7CF41F3BBD83BBDCB469CD2748177A7C7126877F0BF72BA8F9511B1EE1D2FBA0227566D8A70E3D39084966B93D63EB77A696AC2B1BC2EA2DA65B01F73F03C45962EAD174B9E787C9D80739BF3F82B9739BA5CAB05A4B7FA3EF759EE2F9D03B590BDD32C62FBD7DF1C617DCCD17D169EDCCF2801610A2C01EEF5EFB9906983FB66DC8FBB528486A99A1C51E17D04D3AD8A26D39DD10726AAE8BB820C7490C823A84C623277AF63FE0CAFC18697914FB0E249510FB8DD497EBC117DDAA32BC157962B57E568E3C3FF1616FEB8BCFF07A10C3040EA0C0000 , N‘6.1.3-40302‘)

如上图所示:第一段创建表MyEntities,是我们的目标,这没错,很正常。

第二段:创建表_MigrationHistory,这是什么鬼。其实这就是EF6框架用来维护模型的表,

[MigrationId]:遍号,主键,存储设计类中Id,其实就是本次迁移记录的名称。

[ContextKey]:标记当前上下文的识别码,主键,因为CodeFirst支持多个上下文实例,所以用这个字段来标记。

[Model]:模型,当前模型的具体描述,加密了。

[ProductVersion]:EF框架的版本号。

EF6框架通过这张表具体记录每次迁移变化,也是通过这张表来检查程序中的对象和数据库中的关系是否一致。

下面继续在控制台输入:Update-DataBase –verbose(或者-v)。更新数据库,并且查看执行的具体sql语句。

结果:

哦,通过查看错误信息,我们可以知道原来是当前配置的是MSSqlServer,而我本机又没有安装MSSqlServer数据库实例,所以当然连接不上了。我们的目标是MySql数据库,所以就要修改App.config中连接字符串了。

打开App.config:

找到连接字符串:

<connectionStrings>
    <add name="MyContext" connectionString="data source=(LocalDb)\MSSQLLocalDB;initial catalog=CodeFirstDemo.MyContext;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
  </connectionStrings>

修改为MySql的连接字符串:

<connectionStrings>
    <add name="MyContext" connectionString="Data Source=127.0.0.1;port=3306;Initial Catalog=CodeFirstDemoDb;user id=root;password=1234;" providerName="MySql.Data.MySqlClient"/>
  </connectionStrings>

再次在控制台输入:Update-DataBase –verbose。

这是因为当前的Sql生成器依然是MSSqlServer,那么如何启动MySql的Sql生成器呢?

在Migration文件夹中的配置类Congifuration的构造方法中:

public Configuration()
        {
            AutomaticMigrationsEnabled = false;
            SetSqlGenerator("MySql.Data.MySqlClient", new MySql.Data.Entity.MySqlMigrationSqlGenerator());//设置Sql生成器为Mysql的
        }

再次在控制台输入:Update-DataBase –verbose。

我擦泪!!!

这是MyEntity.Name属性为string类型,直接映射到MySql中的话是longtext,而MySql支持最大长度为767bytes。

可以用的是DataAnnotations(数据注释)方式,配置MyEntity.Name属性的映射规则:

public class MyEntity
    {
        public int Id { get; set; }
        [MaxLength(100)]
        public string Name { get; set; }
    }

 

未完待续……

 

 

 

 

 

细数MySql中特别迷人(keng)之处

时间: 2024-08-08 09:29:32

EF6(CodeFirst)+Mysql开发脱坑指南的相关文章

大数据 SQL Boy 脱坑指南

不可否认的是 SQL 是一个伟大的发明,它让增删改查的操作更加地便捷化,而且 SQL 的学习成本相对其他编程语言来说较低,被逼到会写 SQL 的运营和产品我都见过不少... 大数据行业跟 SQL 更是有不解之缘,可谓"万物皆可 SQL 化",从Hive/SparkSQL等最原始的最普及的 SQL 查询引擎,到 Impala/Presto/ClickHouse/Kylin/Phoenix 等等 OLAP 引擎,再到流式的 Structured Streaming/Flink SQL/Ka

微信小程序开发填坑指南V1

近期用了一星期的时间,开发了一个小程序.小程序名称是:小特Jarvis,取自钢铁侠的管家. 后台采用C#编写,WebAPI接口.其实开发时间并不多,小程序本身提供的API,相比公众号的API来说,已经封装了好多东西,我们只负责简单调用即可.而且,提供的开发工具也很方便,开发环境和VisualStudio很类似,包括快捷键(不知道Java的开发员是不是也有这感觉?) 好了说重点.今天是个总结,把这一星期开发时遇到的坑整理下,希望其他人遇到时能有个参考.其实开发的坑不多,部署的坑最多.开始咯 1,多

EF6 Codefirst+MySql 数据库迁移

简介 项目使用MSSql作为数据库,但是因为SQL服务器贵那么一点,并发连接差那么一点,要把数据迁移到MySQL,顺带迁移过程以及问题. 环境 · Visual Studio 2013 · MySQL 5.7 · Entity Framework 6.1.3 正文 迁移过程 1. 安装MySQL,顺带安装 MySQL for Visual Studio.MySQL Connector Net 2. 在Entity Framework 项目和 WebSite项目中添加Nuget包,MySql.Da

移动端web开发填坑指南之——百分比的过错

在移动端开发中,特别是在安卓的微信端进行开发的时候会遇到各种奇奇怪怪的坑.慢慢写慢慢填坑. 今天遇到的是,移动端中对一个div指定了height:100%;之后在安卓微信浏览器端遇到当input调起软键盘之后整个页面布局被重新resize后压扁,而ios则不会遇到这个问题. 通过实验,发现用通过js获取当前可是窗口高度后再对该div进行赋值之后,此时在安卓调起软键盘就不会出现这样的问题. 可见时对高度进行百分比设置的错.因为100%导致整个页面在软键盘弹出后进行了重新的resize操作. 做一个

毕业了,聊一聊计算机实验室的脱坑指南

前文已经说过,你可以提前通过学长学姐咨询实验室的情况,来选择自己心仪的实验室,避免进入自己不喜欢的实验室.那么如果已经不小心进入到了自己不喜欢的实验室怎么办,这里提供一些有用的建议. 1.离开你所在的项目组或者离开你所在的实验室 对,你没看错,就是离开.很多人可能会有疑问,我都已经进来了,怎么出去啊!?Are you kidding me? 这不是演习,其实,在进入到项目组以后,还是有机会离开的.关键是你如果看到机会,一定要抓住,别思前想后,犹犹豫豫,最后肯定会后悔. 当时我进入到项目组以后,由

erlang开发经验谈:防坑指南

任何语言在使用中都会遇到这样那样的问题,erlang也是.这里整理下我遇到的一些问题,避免继续踩坑.说实话,"防坑指南"这个标题有点过于标新立异,不过还是希望能引起重视,避免在实际开发中重复犯这些问题. '--' 运算 1> [1,2,3,4] -- [1] -- [2]. [2,3,4] 算是erlang经典的问题了.这是从后面算起的,先算 [1] -- [2] ,得到 [1] 后被 [1,2,3,4] --,最后得到 [2,3,4] 如果是 ++ 也是一样的,从后面开始算起,

MySQL开发指南

数据库开发是数据库管理系统(DBMS)和数据库应用软件设计研发的总称,数据运维.参与数据库生产环境的问题优化和解决等方面的事宜. 1.关于MySQL数据库 2.搭建MySQL环境 3.入门常用SQL.官方文档的使用 对于开发而言: SQL是基础中的基础!!! SQL是操作和检索关系型数据库的标准语言,标准SQL语句可用于操作关系型数据库. 下面是基于MySQL的SQL分析研究: 一.DQL(Data Query Language,数据查询语言)语句 主要由于select关键字完成,查询语句是SQ

安装Seafile Server 7.1.3 不完全避坑指南

容易踩的坑 解决依赖关系是安装seafile server的第一个坑. 官方提供的安装包,大部分依赖都已经打包在包里了, 只有seahub依赖的部分Python包,因为使用了C语言,编译安装时必须和Python的版本对应(这也是之前Windows版本必须安装指定版本python的原因),由于无法预知客户端的Python版本,所以无法包含在安装包中. MySQL/Mariadb数据库配置是第二个坑. 有些系统安装的MySQL/Mariadb数据库,默认配置是不允许root用户通过网络连接服务器的,

EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(一)

前言 本系列源自对EF6 CodeFirst的探索,但后来发现在自己项目中构建的时候遇到了一些问题以及一些解决方法,因此想作为一个系列写下来. 本系列并不是教你怎么做架构设计,但可以参照一下里面的方法,EF系列大都采用DDD的构建方式,这也是目前最流行的.如果你想对DDD有所了解,可以在园子当中寻找那些DDD方面的文章或者是在CodePlex上下载相关的DDD设计模型源码进行研究. 如果你是一个新人或者是没有用过EF6 CodeFirst的人,那么本系列将带你一步一步构建自己的解决方案平台.如果