EF Core 二 、 入门 EF Core
入门EF Core
我们将开始真正的EF之旅了,这里使用SqlServer数据,然后DbFirst;
为嘛使用SqlServer,目前公司的整体业务全部在SqlSever,所以很多产品业务都是依托于这个,当然也在考虑做数据库切换,切换EF Core就是开始,为后续做好准备,目前SqlServer的linux集群部署太麻烦了,至少我是这样认为的,而且很多客户也都人格上排斥 .... 说多了都是泪 ....
然后就是DbFirst,公司是业务型公司,注重业务需求的设计,所以在需求开发之前,表结构的设计基本上都已经确定,基于现在的业务以及背景,可能DbFirst更加适合,当然Code First也不会丢掉的
一、安装 EF Core
新建类库,用来引用 Microsoft.EntityFrameworkCore.SqlServer

如果在项目中有类似的第三方程序集引用,建议放入统一的程序集,这样不用到处维护引用信息;而且有利于后期解耦,其他业务相关的都依赖统一接口就可以,这样具体的实现引用只是一个插件而已;
二、生成数据表结构
为了做测试,这里生成两张表,TestTable,以及TestTableDetail,用来模拟主从表的场景;一步步来啊
CREATE TABLE [dbo].[TestTable](
[Id] [INT] NOT NULL,
[Name] [NVARCHAR](200) NOT NULL,
PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[TestTableDetail](
[Id] [INT] NOT NULL,
[PID] [INT] NOT NULL,
[Name] [NVARCHAR](200) NOT NULL,
PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
三、建立实体对象
建立实体对象,用来与数据库的对象进行匹配
[Table("TestTable")]
public class TestTable
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
}
[Table("TestTableDetail")]
public class TestTableDetail
{
[Key]
public int Id { get; set; }
public int PID { get; set; }
public string Name { get; set; }
}
四、创建DbContext上下文
/// <summary>
/// 自定义 数据上下文
/// </summary>
public class MyDbContext : DbContext
{
public DbSet<TestTable> TestTables { get; set; }
public DbSet<TestTableDetail> TestTableDetails { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
//写入连接字符串
optionsBuilder.UseSqlServer("Data Source=.\\SQLSERVER2014;Initial Catalog=EfCore.Test;User ID=sa;Pwd=1");
}
}
DbContext是EF操作数据库的窗口,我们将为每个表来创建一个DbSet<>泛型类属性,用来操作具体的表对象;DbSet支持Linq操作;这里两个知识点:
1.如何配置连接字符串
如果是Asp.net Core程序,通常配置在Startup.cs中,需要导入 Microsoft.Extensions.Configuration 名命空间方可使用,按如下方式进行注册
public void ConfigureServices(IServiceCollection services) { services.AddDbContext<BloggingContext>(options => options.UseSqlServer(Configuration.GetConnectionString("BloggingDatabase")));
}
看下源码
EFCore.SqlServer
public static DbContextOptionsBuilder UseSqlServer(
[NotNull] this DbContextOptionsBuilder optionsBuilder,
[NotNull] string connectionString,
[CanBeNull] Action<SqlServerDbContextOptionsBuilder> sqlServerOptionsAction =
null)
{
Check.NotNull(optionsBuilder, nameof(optionsBuilder));
Check.NotEmpty(connectionString, nameof(connectionString));
var extension =
(SqlServerOptionsExtension)GetOrCreateExtension(optionsBuilder).WithConnectionString(connectionString);
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
ConfigureWarnings(optionsBuilder);
sqlServerOptionsAction?.Invoke(new
SqlServerDbContextOptionsBuilder(optionsBuilder));
return optionsBuilder;
}
对DbContextOptionsBuilder进行扩展,提供了UseSqlServer方法,连接信息的提供都是通过 DbContextOptionsBuilder 来实现
针对WinForms以及WPF应用呢?我测试验证的就是控制台应用
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
//写入连接字符串
optionsBuilder.UseSqlServer("Data Source=.\\SQLSERVER2014;Initial Catalog=EfCore.Test;User ID=sa;Pwd=1");
}
这里我是固定了连接字符串,可以根据配置文件来写入了;可以看到也是对 DbContextOptionsBuilder 的 UseSqlSerer方法的调用;
查看源码:
DbContext
//定义虚方法OnConfiguring的位置
protected internal virtual void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
}
在InternalServiceProvider中进行了初始化调用,调用了OnConfiguring,从而进行了连接字符串的赋值;

2.是否需要为每个类都定义DbSet属性
如果业务系统过大,我们真的会定义一个DbContext,然后将所有Entity定义成DbSet<>?应该不会,这时我们可以通过反射来实现;
1.通过实现一个反射读取类,来动态读取实体类,也就是读取类具备 “Table”属性的目标类,或者自己集成一个父类用来识别实体类;
2.将读取到的实体类,动态加入到DbContext的实体模型中;
通过 重写 OnModelCreating 方法;微软官方文档地址:https://docs.microsoft.com/zh-cn/ef/core/modeling/
通过调用ModelBuilder.Entity方法直接贴代码:
/// <summary>
/// 自定义 数据上下文
/// </summary>
public class DynamicDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
//写入连接字符串
optionsBuilder.UseSqlServer("Data Source=.\\SQLSERVER2014;Initial Catalog=EfCore.Test;User ID=sa;Pwd=1");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var assembly = Assembly.GetExecutingAssembly();
foreach (Type type in assembly.ExportedTypes)
{
if (type.IsClass && type != typeof(EntityBase) && typeof(EntityBase).IsAssignableFrom((Type) type))
{
var method = modelBuilder.GetType().GetMethods().FirstOrDefault(x => x.Name == "Entity");
if (method != null)
{
method = method.MakeGenericMethod(type);
method.Invoke(modelBuilder, null);
}
}
}
base.OnModelCreating(modelBuilder);
}
}
整体思路还是两步走,先找到实体的实现类,然后通过调用DbContenxt的Entity方法;我们来看下DbContext源码;

最后通过Metadata.AddEntityType加入到实体模型,Metadata用来存储实体元数据;
还有两外一种实现方式,其实也就是衍生的方式了,因为查看源码得知最后实体被加入到了Medel中,那何不直接加入呢?

调用代码:
var myDbContext = new DynamicDbContext();
var list = myDbContext.Set<TestTable>().ToList();
Console.WriteLine($"TestTable Count: {list.Count}");
if (!list.Any()) return;
Console.WriteLine($"TestTable Detail ---------------- ");
foreach (var item in list)
{
Console.WriteLine($"ID : {item.Id} , Name : {item.Name}");
}
Console.WriteLine($"------------------------");
来看下执行效果吧....

这里的实现让我想到了ABP数据仓储的实现,ABP为每个实体创建一个仓储对象,不需要手动一个个创建,可以查看我的ABP系列 => ABP 数据访问 - IRepository 仓储 ,可以参考ABP仓储管理的思想;大家也可以去看下
五、数据访问
好了,回到最初的实现思路上,前面的准备工作都做的差不多了,该正式跑一把数据了....
public static void Query_查询数据_全量查询()
{
var myDbContext = new MyDbContext();
var list = myDbContext.TestTables.ToList();
Console.WriteLine($"TestTable Count: {list.Count}");
if (!list.Any()) return;
Console.WriteLine($"TestTable Detail ---------------- ");
foreach (var item in list)
{
Console.WriteLine($"ID : {item.Id} , Name : {item.Name}");
}
Console.WriteLine($"------------------------");
}
通过控制台应用,执行上述方法,即可查询到TestTable中的数据

到此我们基本就开始使用EF Core,实现了数据访问;后续将开始对EF的其他使用持续进行分析,以及一些高阶应用;
文章后面附上EFCore的源码地址,一起看源码,一起学习 https://github.com/dotnet/efcore
帮助博客园推广下:https://www.cnblogs.com/cmt/p/14003277.html
EF Core 二 、 入门 EF Core的更多相关文章
- K8S+GitLab-自动化分布式部署ASP.NET Core(二) ASP.NET Core DevOps
一.介绍 前一篇,写的K8S部署环境的文章,简单的介绍下DevOps(Development和Operations的组合词),高效交付, 自动化流程,来减少软件开发人员和运维人员的沟通.Martin ...
- EF Core 快速上手——EF Core 入门
EF Core 快速上手--EF Core 介绍 本章导航 从本书你能学到什么 对EF6.x 程序员的一些话 EF Core 概述 1.3.1 ORM框架的缺点 第一个EF Core应用 本文是对 ...
- asp.net core系列 30 EF管理数据库架构--必备知识 迁移
一.管理数据库架构概述 EF Core 提供两种主要方法来保持 EF Core 模型和数据库架构同步.一是以 EF Core 模型为基准,二是以数据库为基准. (1)如果希望以 EF Core 模型为 ...
- EF Core 快速上手——EF Core的三种主要关系类型
系列文章 EF Core 快速上手--EF Core 入门 本节导航 三种数据库关系类型建模 Migration方式创建和习修改数据库 定义和创建应用DbContext 将复杂查询拆分为子查询 本 ...
- asp.net core系列 31 EF管理数据库架构--必备知识 反向工程
一. 反向工程 反向工程是基于数据库架构,生成的实体类和DbContext类代码的过程,对于Visual Studio开发,建议使用PMC.对于其他开发环境,请选择.NET Core CLI工具( ...
- asp.net core 系列 20 EF基于数据模型创建数据库
一.概述 本章使用 Entity Framework Core 构建执行基本数据访问的 ASP.NET Core MVC 应用程序.使用迁移(migrations)基于数据模型创建数据库,是一种cod ...
- EF 6.x、EF Core实现dynamic动态查询和EF Core实现多个上下文实例池你了解多少?
前言 很长一段时间没有写博客了,今天补上一篇吧,偶尔发现不太愿意写博客了,太耗费时间,不过还是在坚持当中,毕竟或许写出来的东西能帮到一些童鞋吧,接下来我们直奔主题.无论是在在EF 6.x还是EF Co ...
- 讨论过后而引发对EF 6.x和EF Core查询缓存的思考
前言 最近将RabbitMQ正式封装引入到.NET Core 2.0项目当中,之前从未接触过是个高大上的东东跟着老大学习中,其中收获不少,本打算再看看RabbitMQ有时间写写,回来后和何镇汐大哥探讨 ...
- Asp.Net Core WebAPI入门整理(二)简单示例
一.Core WebAPI中的序列化 使用的是Newtonsoft.Json,自定义全局配置处理: // This method gets called by the runtime. Use thi ...
随机推荐
- docker-阿里云加速
系统版本 centos7 阿里云登录 ->容器镜像服务->镜像加速器 复制下面的直接执行即可 sudo mkdir -p /etc/docker sudo tee /etc/doc ...
- linux(centos8):基于java13安装rocketmq-4.7.1(解决jdk不兼容的报错)
一,Rocketmq是什么? 1, RocketMQ是一个队列模型的消息中间件,具有高性能.高可靠.高实时.分布式特点 相比kafka,rocketmq的实时性更强 2,官方网站: http://ro ...
- centos 安装docker方法2
1 更新yum yum -y update 2 执行命令 linux 安装dockersudo wget -qO- https://get.docker.com | sh解释如下sudo 使用root ...
- 白话k8s-Pod的组成
k8s的所有功能都是围绕着Pod进行展开的,我们经常会看到类似这样一张图 告诉我们,Pod是一组container的集合,container之间可以通过localhost:port的方式直接访问. 感 ...
- spring boot报错:Invalid bound statement (not found): com.
经检查发现mapper的namespace没写全导致的 正确应该写成这样就可以了:
- C++学习---栈的构建及操作
一.顺序栈 #include <iostream> using namespace std; #define MAXSIZE 100 //栈的最大容量 typedef struct { i ...
- oracle oracle sqldeveloper 12505 创建连接失败
ref:http://blog.csdn.net/yangwenxue_admin/article/details/45062557
- maven 配置文件 settings.xml pom.xml
maven涉及的配置文件一般有三个:(作用范围依次减小,优先级依次升高) 全局配置(maven安装包中):${M2_HOME}/conf/settings.xml 用户配置(该文件是拷贝全局配置而来的 ...
- Windows搭建Hexo系统
date: 2018-11-16 17:10:51 updated: 2018-11-16 20:04:43 1.安装Git 下载Windows下的Git客户端并安装,安装很简单,基本一路Next下去 ...
- js工厂函数
经常会遇到工厂函数这个词,不过javascript不是严格的面向对象语言,不像java,C#拥有类,所以工厂函数会变得比较模糊. 简单来讲,就是创建一个可以用来创建实例的函数,这样每一个实例都是独立的 ...