使用VS2013 + EF6 + .NET4.5 连接Mysql数据库
1、安装插件
在使用Visual Studio 2013添加ADO.NET实体数据模型新建连接时,默认是没有Mysql选项的。此时我们需要安装两个东西:
1、mysql-for-visualstudio:Mysql的Visual Studio插件,推荐1.2.3版本
2、mysql-connector-net:.net连接Mysql的程序,推荐6.8.3,版本。如果安装高版本可能导致一系列问题。详见:http://blog.csdn.net/niewq/article/details/41877301。
2、新建ADO.NET实体数据模型
2、1、按图操作,添加实体数据模型:
2.2、一切进展貌似都很顺利。接下来你可能会看到Visual Studio给出了如下的提示:
2.3、解决方法:在NuGet的控制台输入以下命令:
Install-Package EntityFramework -Version 6.0.0
Install-Package EntityFramework.zh-Hans -Version 6.0.0
Install-Package MySql.Data.Entity.EF6
每个命令输入之后按回车执行,你会发现前两个都很顺利,但是第三个却报错了:
此时我们不通过NuGet添加这个引用,具体步骤为将MySQL Connector Net 6.8.3\Assemblies\v4.5(视你的项目使用的.net版本而定,我的是.net 4.5)下的所有dll文件引用进来。我的机器上安装目录如下:
全部引用
然后在应用程序配置文件中添加:<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6"></provider>
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> </configSections> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup> <entityFramework> <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" /> <providers> <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6"></provider> <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> </providers> </entityFramework> </configuration>
然后,一定要重新生成项目!!!
2.4、继续下面的步骤,成功。
3、Mysql数据库改动
接下来,就是从数据库选择表以生成EDMX文件,但是在此过程中,你可能会遇到下列问题:
VS给出了一堆的提示,但是重点就是红框内的:表“TableDetails”中列“IsPrimaryKey”的值为 DBNull。这个问题的解决方案在这。我们按照文中所说,设置数据库testbak(我用的数据库):
1、重启数据库服务器。
2、use testbak;
3、set global optimizer_switch='derived_merge=OFF';
再去尝试一次,成功!!!
解决方案窗口多了很多文件:
每个实体数据模型生成一个context类,数据库每个表生成一个entity类。在Model1.edmx中包含的两个重要的文件Model1.Context.tt和Model1.tt。第一个是用于生成Context类的T4模板,第二是用于生成表映射实体类(POCO类,POCO:Plain Old CLR Object)的T4模板。
Model1.Context.cs是从System.Data.Entity.DbContext类继承。EF4.1中则是从ObjectContext类继承。DbContext类与ObjectContext类似,它对ObjcetContext类进行包装更利于开发的三种模式:CodeFirst、Model First、Database First。
4、DbContext
DbContext是EntityFramework很重要的部分,连接域模型与数据库的桥梁,是与数据库通信的主要类。
DbContext主要负责以下活动:
EntitySet::DbContext包含了所有映射到表的entities
Querying:将Linq-To-Entities转译为Sql并发送到数据库
Change Tracking:从数据库获取entities后保留并跟踪实体数据变化
Persisting Data:根据entity状态执行Insert、update、delete命令
Caching:DbContext的默认第一级缓存,在上下文中的生命周期中存储entity
Manage Relationship:DbContext在DbFirst模式中使用CSDL、MSL、SSDL管理对象关系,Code first中使用fluent api 管理关系
Object Materialization:DbContext将物理表转成entity实例对象
//DbContext实例化: using (var ctx = newSchoolDBEntities()) { //Can perform CRUD operation using ctx here.. } //将DbContext转为ObjectContext using (var ctx = newSchoolDBEntities()) { var objectContext = (ctx as System.Data.Entity.Infrastructure.IObjectContextAdapter).ObjectContext; //use objectContext here.. }
详见:http://www.cnblogs.com/xuf22/articles/5513283.html
5、增删改查操作
5.1 IDAL
using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; namespace ADO.NETEFDemo { public interface IDAL<T> where T : class,new() { /// <summary> /// 增 /// </summary> /// <param name="model"></param> /// <returns></returns> int Add(T model); /// <summary> /// 删 /// </summary> /// <param name="whereLambda"></param> /// <returns></returns> int Delete(Expression<Func<T, bool>> whereLambda); /// <summary> /// 改 /// </summary> /// <param name="whereLambda"></param> /// <param name="propertyNames"></param> /// <param name="perpertyValues"></param> /// <returns></returns> int Update(Expression<Func<T, bool>> whereLambda, string[] propertyNames, object[] perpertyValues); /// <summary> /// 查 /// </summary> /// <param name="whereLambda"></param> /// <returns></returns> List<T> GetModelList(Expression<Func<T, bool>> whereLambda); } }
5.2 DAL
using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace ADO.NETEFDemo { public class DAL<T> : IDAL<T> where T : class,new() { /// <summary> /// 增 /// </summary> /// <param name="model"></param> /// <returns></returns> public int Add(T model) { using (testbakEntities db = new testbakEntities()) { db.Set<T>().Add(model); return db.SaveChanges(); } } /// <summary> /// 删 /// </summary> /// <param name="whereLambda"></param> /// <returns></returns> public int Delete(Expression<Func<T, bool>> whereLambda) { using (testbakEntities db = new testbakEntities()) { var dbQuery = db.Set<T>(); //先查询 对应表的 集合 var list = dbQuery.Where(whereLambda).ToList(); //遍历集合 里要删除的元素 foreach (var item in list) { //标记为 删除状态 dbQuery.Remove(item); } return db.SaveChanges(); } } /// <summary> /// 改 /// </summary> /// <param name="whereLambda"></param> /// <param name="propertyNames"></param> /// <param name="perpertyValues"></param> /// <returns></returns> public int Update(Expression<Func<T, bool>> whereLambda, string[] propertyNames, object[] perpertyValues) { using (testbakEntities db = new testbakEntities()) { //1、查询要修改的对象集合 var list = db.Set<T>().Where<T>(whereLambda).ToList(); //2、获取要修改的对象的类型 Type t = typeof(T); //3、循环要修改的实体对象,并根据要修改的属性名修改对象对应的属性值 foreach (var item in list) { //循环 要修改的属性 名称, 并 反射取出 t 中的 属性对象 for (int index = 0; index < propertyNames.Length; index++) { //获取要修改的属性名 string pName = propertyNames[index]; //获取属性对象 PropertyInfo pi = t.GetProperty(pName); //调用属性对象的 SetValue方法 为当前循环的 item对象 对应的属性赋值 pi.SetValue(item, perpertyValues[index], null); } } return db.SaveChanges(); } } /// <summary> /// 查 /// </summary> /// <param name="whereLambda"></param> /// <returns></returns> public List<T> GetModelList(Expression<Func<T, bool>> whereLambda) { using (testbakEntities db = new testbakEntities()) { return db.Set<T>().Where(whereLambda).ToList(); } } } }
5.3 BLL
using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; namespace ADO.NETEFDemo { public static class BLL<T> where T : class,new() { private static IDAL<T> dal = new DAL<T>(); /// <summary> /// 新增 /// </summary> /// <param name="model"></param> public static int Add(T model) { return dal.Add(model); } /// <summary> /// 删除 /// </summary> /// <param name="whereLambda"></param> public static int Delete(Expression<Func<T, bool>> whereLambda) { return dal.Delete(whereLambda); } /// <summary> /// 修改 /// </summary> /// <param name="whereLambda"></param> /// <param name="propertyNames"></param> /// <param name="perpertyValues"></param> /// <returns></returns> public static int Update(Expression<Func<T, bool>> whereLambda, string[] propertyNames, object[] perpertyValues) { return dal.Update(whereLambda, propertyNames, perpertyValues); } /// <summary> /// 查询 /// </summary> /// <param name="whereLambda"></param> /// <returns></returns> public static List<T> GetModelList(Expression<Func<T, bool>> whereLambda) { return dal.GetModelList(whereLambda); } } }
5.4 调用
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ADO.NETEFDemo { class Program { static void Main(string[] args) { GetArticleList(); AddArticle(); GetArticleList(); UpdateArticle(); GetArticleList(); DeleteArticel(); GetArticleList(); Console.ReadKey(); } /// <summary> /// 更新 /// </summary> private static void UpdateArticle() { int result = BLL<t_crobot_reship_articles> .Update(e => e.title.Contains("EF"), new[] { "title", "update_time" }, new object[] { "我是使用EF修改过标题的文章", DateTime.Now }); if (result >= 0) { Console.WriteLine("更新成功"); } else { Console.WriteLine("更新失败"); } Console.WriteLine(); } /// <summary> /// 删除 /// </summary> private static void DeleteArticel() { int result = BLL<t_crobot_reship_articles>.Delete(e => e.title.Contains("EF")); if (result >= 0) { Console.WriteLine("删除成功"); } else { Console.WriteLine("删除失败"); } Console.WriteLine(); } /// <summary> /// 新增 /// </summary> private static void AddArticle() { t_crobot_reship_articles model = new t_crobot_reship_articles(); model.create_time = DateTime.Now; model.module_id = 1; model.adword_id = 20; model.pick_id = 1; model.vote_id = "1"; model.title = "我是使用EF添加的文章"; model.content_id = 1; model.release_url = "http://www.sss.com"; model.state = true; int result = BLL<t_crobot_reship_articles>.Add(model); if (result >= 0) { Console.WriteLine("新增成功"); } else { Console.WriteLine("新增失败"); } Console.WriteLine(); } /// <summary> /// 获取文章列表 /// </summary> private static void GetArticleList() { List<t_crobot_reship_articles> articleList = BLL<t_crobot_reship_articles> .GetModelList(e => e.state == true); Console.WriteLine("文章总数:" + articleList.Count.ToString()); foreach (t_crobot_reship_articles model in articleList) { Console.WriteLine("标题:" + model.title); } Console.WriteLine(); } } }
5.5 结果
6、小结
文章中需要使用的插件下载地址:mysql-for-visualstudio-1.2.3.zip、mysql-connector-net-6.8.3.zip。
具体的操作步骤并不一定按文中所述的来。