(1)Microsoft.EntityFrameworkCore
(2)Microsoft.EntityFrameworkCore.Design
(3)Microsoft.EntityFrameworkCore.Tools
(4)MySql.Data.EntityFrameworkCore (这里以MySql为例)
(5)MySql.Data.EntityFrameworkCore.Design
(上面的3个是EF Core的包,第4个是连接Mysql的包。 如果使用的是别的数据库请更换对应的连接数据库Nuget包,
第5个包是为了进行实体自动映射时需要的。 具体作用 看第二部操作)
1)打开程序包控制台
2) 输入 指令将制定数据库的所有表 转成实体写到制定文件夹下:
例: Scaffold-DbContext "Data Source=localhost;Initial Catalog=test;User ID=root;Password=" MySql.Data.EntityFrameworkCore -OutputDir Models
Scaffold-DbContext "Data Source=【数据库服务器地址】;Initial Catalog=【数据库的名称】;User ID=【用户名】;Password=【密码】" MySql.Data.EntityFrameworkCore -OutputDir Models【打算保存到models的文件夹】
3)修改模型后 同步 Model 只需要在 Scaffold-DbContext 后面加上一句 -Force
例: Scaffold-DbContext -Force "Data Source=localhost;Initial Catalog=test;User ID=root;Password=" MySql.Data.EntityFrameworkCore -OutputDir Models
打开输入model的文件夹下的 context文件。
修改里面的OnConfiguring 的 UseMySQL中的连接字符串
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
optionsBuilder.UseMySQL("Data Source=localhost;Initial Catalog=test;User ID=root;Password=;charset = 'utf8';pooling = true;");
}
}
Data Source=【数据库服务器地址】;Initial Catalog=【数据库的名称】;User ID=【用户名】;Password=【密码】;
charset = 'utf8';pooling = true;
(还有几个常用的连接字符串配置 :
charset = 'utf8' 向服务器请求连接所使用的字符集,默认:无
pooling = true; 是否使用线程池,默认 true
Allow User Variables=True; 是否允许 SQL 中出现用户变量,默认 false
AllowZeroDateTime=True; 日期时间能否为零,默认 false)
更多的连接字符串配置参考: https://www.cnblogs.com/micro-chen/p/5755774.html
(目前这种方法可以直接创建对象 new 来调用。 如果想注册成服务则在 管道末端注入来使用
在Startup.cs,然后在ConfigureServices函数下添加如下代码来注册
services.AddDbContext(
options => options.UseMySQL("Data Source=localhost;Initial Catalog=test;User ID=root;Password=;charset = 'utf8';pooling = true;")
);
这样就可以以注入的方式进行调用)
ef 的使用方法很简单
首先先创建上下文对象:
public testContext EfContent { get; set; }
(下面所有的方法都是原生提供的。如果有业务需求或者优化可以在此基础上进行2次封装)
新增:
public int Add(object model)
{
//1.异步方法新增 (方法加async)
await EfContent.AddAsync(model);
//2.同步方法创建
EfContent.Add(model);
//3.泛型创建
EfContent.Add(model); //如果使用此方法传入的model必须是你选定的类型
//4.对应表的创建
EfContent.FpArticle.Add(model); //如果使用此方法传入的model必须是你选定的类型
//异步的保存要用 await EfContent.SaveChangesAsync();
return EfContent.SaveChanges() //真正的保存到数据库
}
删除 (ef的删除必须先获取才可以进行Model删除):
public int Delete(object model)
{
//1.异步方法删除 (方法加async)
await EfContent.Remove(model);
//2.同步方法删除
EfContent.Remove(model);
//3.泛型删除
EfContent.Remove(model); //如果使用此方法传入的model必须是你选定的类型
//4.对应表的删除
EfContent.FpArticle.Remove(model); //如果使用此方法传入的model必须是你选定的类型
//异步的保存要用 await EfContent.SaveChangesAsync();
return EfContent.SaveChanges() //真正的保存到数据库
}
修改:
public int Update(object model)
{
//1.异步方法修改 (方法加async)
await EfContent.Update(model);
//2.同步方法修改
EfContent.Update(model);
//3.泛型修改
EfContent.Update(model); //如果使用此方法传入的model必须是你选定的类型
//4.对应表的修改
EfContent.FpArticle.Update(model); //如果使用此方法传入的model必须是你选定的类型
//异步的保存要用 await EfContent.SaveChangesAsync();
return EfContent.SaveChanges() //真正的保存到数据库
}
查询 :
EfContent.Query(); //查询则必须指定到实体
此外还有批量更新和批量查询:
EfContent.AddRange();
EfContent.UpdateRange();
有需要的都可以根据提供的方法进行封装。 记住最后一定要savechange,只有这步才是真正的执行到数据库。
除此之外 EF 还支持Sql语句查询,使用的方法和mysql 差不多:
Datatable datatable = new datatable ();
using (var connection = EfContent.Database.GetDbConnection()) //创建连接
{
using (var cmd = connection.CreateCommand()) //创建查询对象
{
await EfContent.Database.OpenConnectionAsync();
cmd.CommandText = cmdText; //设置查询类型
if (commandParameters != null && commandParameters.Length > 0)
cmd.Parameters.AddRange(commandParameters);
DbProviderFactory provider = DbProviderFactories.GetFactory(connection);
using (DbDataAdapter dbDataAdapter = provider.CreateDataAdapter())
{
dbDataAdapter.SelectCommand = cmd;
dbDataAdapter.Fill(datatable); //导出数据到datatable
}
}
}
踩过的坑:
1) ef 其实是同步数据尝试的用的ef,在这个过程中发现了一个问题。我的来源表中有个字段 status 是tinyint 类型的 转换到c# 中是byte类型。 但是数据里中的status有存为 -1的数据。但是在c# byte不支持赋值为 -1,尝试更改model类型也无济于事(因为和最终的映射的model和表的类型不匹配会报错) , 最后因为我需要操作的主字段不包含 这个字段。我将Content中这个表的这个字段的映射关系 注释掉了。才得以同步不报错。如果是相同需求的。只需要同步指定字段。或者某些字段的操作有问题但不影响主业务的操作,可以将不需要的字段映射注释掉。
2) 在批量更新的时候。我使用的是new 的方式创建的上下文。 之前是将上下文创建在while外,导入效率会随着时间的增加变得越来越慢。那是因为我使用的是update,但是对象还是之前的那个导致savechang操作的数量不断叠加。所以后来将创建上下文。放在while里每次都新创建(启用了连接池)。效率提升了很多。
附.数据实体转换到model的对应关系
字段对应关系图 转载自:https://blog.csdn.net/RainyLin/article/details/84656892