ef 多个左联接查询_.NET 云原生架构师训练营(模块二 基础巩固 EF Core 查询)--学习笔记...

43a6ee7084080a58a2d1f0604ec9f22a.png

2.4.5 EF Core -- 查询

  • 关联数据加载
  • 客户端与服务端运算
  • 跟踪与不跟踪
  • 复杂查询运算
  • 原生 SQL 查询
  • 全局查询筛选器

关联数据加载

学员和助教都在项目分组中,调整模型,删除 Assistant

ProjectGroup 添加 Member 列表

public List<Member> Members { get; set; }

Member 添加 是否助教判断,分组信息

public bool IsAssistant { get; set; }public string GroupId { get; set; }public ProjectGroup Group { get; set; }

Task 添加 学员信息

public Member Member { get; set; }

接下来为每一个表添加一个控制器

一个 Project 对应多个 ProjectGroup

ProjectGroup

namespace LighterApi.Controller
{[ApiController][Route("api/[controller]")]public class ProjectGroupController : ControllerBase{private readonly LighterDbContext _lighterDbContext;public ProjectGroupController(LighterDbContext lighterDbContext){_lighterDbContext = lighterDbContext;}[HttpPost]public async Task<IActionResult> Create([FromBody] ProjectGroup group){_lighterDbContext.ProjectGroups.Add(group);await _lighterDbContext.SaveChangesAsync();return StatusCode((int) HttpStatusCode.Created, group);}[HttpGet][Route("{id}")]public async Task<IActionResult> GetAsync(string id, CancellationToken cancellationToken){var project = await _lighterDbContext.Projects.FirstOrDefaultAsync(p => p.Id == id, cancellationToken);return Ok(project);}}
}

迁移

dotnet ef migrations add RefactoryProjectEntitiesdotnet ef database update

Entity 主键添加自动生成

/// <summary>
/// 主键Id
/// </summary>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public string Id { get; set; }

启动程序,Postman 访问

b0431f581380884ffe56250dbe857fb1.png

ProjectController

[HttpGet]
[Route("{id}")]
public async Task<IActionResult> GetAsync(string id, CancellationToken cancellationToken)
{var project = await _lighterDbContext.Projects.FirstOrDefaultAsync(p => p.Id == id, cancellationToken);return Ok(project);
}

查询项目信息,发现分组信息 groups 为空

fd1b8f7714cca74110729a1e77675e33.png

因为 EF 默认不会查询关联数据,所以需要实现一下

ProjectController 获取项目时使用 Include

[HttpGet]
[Route("{id}")]
public async Task<IActionResult> GetAsync(string id, CancellationToken cancellationToken)
{var project = await _lighterDbContext.Projects.Include(p => p.Groups).FirstOrDefaultAsync(p => p.Id == id, cancellationToken);return Ok(project);
}

由于项目中有分组引用,分组中有项目引用,所以需要在序列化的时候处理循环引用

Startup

services.AddControllers().AddNewtonsoftJson(x=>x.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore);

这样就可以查到项目信息

1d1e37ee72e08818224d20922f0d1997.png

EF Core 为我们提供了三种加载数据的方式

  • 预先加载
  • 显式加载
  • 延迟加载

加载相关数据:https://docs.microsoft.com/zh-cn/ef/core/querying/related-data/

预先加载

预先加载表示从数据库中加载关联数据,作为初始查询的一部分。

在以下示例中,结果中返回的blogs将使用关联的posts填充其 Posts 属性。

using (var context = new BloggingContext())
{var blogs = context.Blogs.Include(blog => blog.Posts).ToList();
}

显式加载

显式加载表示稍后从数据库中显式加载关联数据。

可以通过 DbContext.Entry(...) API 显式加载导航属性。

using (var context = new BloggingContext())
{var blog = context.Blogs.Single(b => b.BlogId == 1);context.Entry(blog).Collection(b => b.Posts).Load();context.Entry(blog).Reference(b => b.Owner).Load();
}

ProjectController

// 显式加载
var project = await _lighterDbContext.Projects.FirstOrDefaultAsync(p => p.Id == id, cancellationToken);
await _lighterDbContext.Entry(project).Collection(p => p.Groups).LoadAsync(cancellationToken);

延迟加载

延迟加载表示在访问导航属性时,从数据库中以透明方式加载关联数据。

使用延迟加载的最简单方式是通过安装 Microsoft.EntityFrameworkCore.Proxies 包,并通过调用 UseLazyLoadingProxies 来启用该包。

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)=> optionsBuilder.UseLazyLoadingProxies().UseSqlServer(myConnectionString);

或在使用 AddDbContext 时:

.AddDbContext<BloggingContext>(b => b.UseLazyLoadingProxies().UseSqlServer(myConnectionString));

EF Core 接着会为可重写的任何导航属性(即,必须是 virtual 且在可被继承的类上)启用延迟加载。 例如,在以下实体中,Post.Blog 和 Blog.Posts 导航属性将被延迟加载。

public class Blog
{public int Id { get; set; }public string Name { get; set; }public virtual ICollection<Post> Posts { get; set; }
}public class Post
{public int Id { get; set; }public string Title { get; set; }public string Content { get; set; }public virtual Blog Blog { get; set; }
}

Project

public virtual ICollection<ProjectGroup> Groups { get; set; }

ProjectController

// 延迟加载
project.Groups// 引用到属性时才加载

客户端与服务端运算

客户端与服务端运算:https://docs.microsoft.com/zh-cn/ef/core/querying/client-eval

由于 SQL Server 提供程序不了解此方法的实现方式,因此无法将其转换为 SQL。 查询的所有其余部分是在数据库中评估的,但通过此方法传递返回的 URL 却是在客户端上完成。

var blogs = context.Blogs.OrderByDescending(blog => blog.Rating).Select(blog => new{Id = blog.BlogId,Url = StandardizeUrl(blog.Url)// 服务端转换SQL,不了解客户端方法实现}).ToList();public static string StandardizeUrl(string url)
{url = url.ToLower();if (!url.StartsWith("http://")){url = string.Concat("http://", url);}return url;
}

需要区分数据运算最终在客户端,还是服务端运行

循环中获取分组会导致多次查询数据库

foreach (var project in _lighterDbContext.Projects)
{project.Groups// 多次查询数据库
}

应该一次性查询

var projects = _lighterDbContext.Projects.ToList();

跟踪与不跟踪

跟踪与不跟踪:https://docs.microsoft.com/zh-cn/ef/core/querying/tracking

默认情况下,跟踪返回实体类型的查询。 这表示可以更改这些实体实例,然后通过 SaveChanges() 持久化这些更改。

非跟踪查询

var blogs = context.Blogs.AsNoTracking().ToList();

还可以在上下文实例级别更改默认跟踪行为:

context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;var blogs = context.Blogs.ToList();

复杂查询运算

复杂查询运算:https://docs.microsoft.com/zh-cn/ef/core/querying/complex-query-operators

联接

var query = from photo in context.Set<PersonPhoto>()join person in context.Set<Person>()on photo.PersonPhotoId equals person.PhotoIdselect new { person, photo };

GroupJoin

var query = from b in context.Set<Blog>()join p in context.Set<Post>()on b.BlogId equals p.PostId into groupingselect new { b, grouping };

SelectMany

var query = from b in context.Set<Blog>()from p in context.Set<Post>()select new { b, p };

GroupBy

var query = from p in context.Set<Post>()group p by p.AuthorId into gselect new{g.Key,Count = g.Count()};

Left Join

var query = from b in context.Set<Blog>()join p in context.Set<Post>()on b.BlogId equals p.BlogId into groupingfrom p in grouping.DefaultIfEmpty()select new { b, p };

原生 SQL 查询

原生 SQL 查询:https://docs.microsoft.com/zh-cn/ef/core/querying/raw-sql

var blogs = context.Blogs.FromSqlRaw("SELECT * FROM dbo.Blogs").ToList();

全局查询筛选器

全局查询筛选器:https://docs.microsoft.com/zh-cn/ef/core/querying/filters

modelBuilder.Entity<Blog>().HasQueryFilter(b => EF.Property<string>(b, "_tenantId") == _tenantId);
modelBuilder.Entity<Post>().HasQueryFilter(p => !p.IsDeleted);

所有实体都继承了基类 Entity,所以这样会把过滤器添加在所有查询上面

LighterDbContext

modelBuilder.Entity<Entity>().HasQueryFilter(x => x.TenantId == "");

GitHub源码链接:

https://github.com/MINGSON666/Personal-Learning-Library/tree/main/ArchitectTrainingCamp/LighterApi

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/505606.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

三国杀服务器改名 插图修改,《三国杀》大幅修改的武将——新旧两版,你更喜欢哪一位...

三国杀中&#xff0c;某些武将因为太强或者太弱&#xff0c;不能适应游戏环境&#xff0c;都会进行修改&#xff0c;例如&#xff1a;李丰、马良、伏皇后、曹冲等等&#xff0c;但这些武将修改之后&#xff0c;原有武将就淘汰了。其实&#xff0c;还有一类武将&#xff0c;技能…

苹果电脑mac_清理Mac苹果电脑DNS缓存

说到清理苹果电脑想必不少网友会说苹果电脑不需要清理&#xff0c;但事实情况是现在对于“苹果电脑清理”的这个话题一直在不断地热议中&#xff0c;虽说Mac OS X系统它的优化比较好&#xff0c;很多小的无效数据文件会自动归类清除&#xff0c;但很多时候一些稍大的数据文件仍…

鼠标追踪没用_【擺评】赛睿里最好用的小手鼠标---Rival 3

拿到这鼠标真的是有段时间了&#xff0c;深度体验了一个多月。先说&#xff0c;这是我用过所有赛睿鼠标里最喜欢的鼠标&#xff0c;虽然它不贵&#xff0c;虽然它是有线的&#xff0c;但真的舒服&#xff01;可能我也没用过几个赛睿的鼠标&#xff0c;仅有以下几款&#xff0c;…

mysql执行一条语句会加锁吗_一条简单的更新语句,MySQL是如何加锁的?

看如下一条sql语句&#xff1a;# table T (id int, name varchar(20))delete from T where id 10&#xff1b;MySQL在执行的过程中&#xff0c;是如何加锁呢&#xff1f;在看下面这条语句&#xff1a;select * from T where id 10&#xff1b;那这条语句呢&#xff1f;其实这…

mysql命令4类_【Mysql】mysql数据库的一些常用命令

一、启动与退出1、进入MySQL&#xff1a;输入命令&#xff1a;mysql -u root -p直接输入安装时的密码即可。此时的提示符是&#xff1a;mysql>2、退出MySQL&#xff1a;quit或exit3、数据库清屏命令&#xff1a;system clear;二、库操作1、创建数据库命令&#xff1a;create…

u2020 华为_华为MateBook X Pro 2020款评测:全面屏商务旗舰再升级

在今年2月24日举办的华为终端产品与战略线上发布会上&#xff0c;华为正式发布了全新升级的MateBook X Pro 2020款笔记本电脑&#xff0c;并且加入了翡冷翠新色&#xff0c;再一次的奠定了产品高端时尚基调。除此之外&#xff0c;华为MateBook X Pro 2020款还升级了第10代智能英…

java -uf_Java如何快速修改Jar包里的文件内容

需求背景&#xff1a;写了一个实时读取日志文件以及监控的小程序&#xff0c;打包成了Jar包可执行文件&#xff0c;通过我们的web主系统上传到各个服务器&#xff0c;然后调用ssh命令执行。每次上传前都要通过解压缩软件修改或者替换里面的配置文件&#xff0c;这样感觉有点麻烦…

java 序列化实例_Java中的序列化与反序列化实例

创建的字节流与平台无关。因此&#xff0c;在一个平台上序列化的对象可以在另一个平台上反序列化。为了使Java对象可序列化&#xff0c;我们实现java.io.Serializable可序列化接口。ObjectOutputStream类包含writeObject()序列化对象的方法。public final voidwriteObject(Obje…

java 代码 _程序员用1.5小时写出的Java代码,让同事瞠目结舌!直呼优秀

1.曾经不止一次在生产中见过类似这样的代码&#xff1a;这有很多变种&#xff0c;例如用 Integer.valueOf(1)、 (Integer)1 之类的&#xff0c;那些细节都不重要。重要的是&#xff1a;凭空用一个 Integer 对象作为锁对象。2.AbstractComponentBuilderTemplateFactory3.HelloWo…

mysql workbench 从model建库_使用MySQL Workbench进行数据库设计——MySQL Workbench用法总结...

转载请注明出处&#xff1a;http://blog.csdn.net/dongdong9223/article/details/48318877 本文出自【我是干勾鱼的博客】 1 简单介绍MySQL Workbench是一款专为MySQL设计的ER/数据库建模工具。它是著名的数据库设计工具DBDesigner4的继任者。你能够用MySQL Workbench设计和创…

mysql5.7 hibenate5.1_5.7 Spring与Hibernate整合应用

下面以一个简单的实例说明Spring与Hibernate的整合策略&#xff0c;步骤如下。1 在SQL Server 2005中创建数据库表数据库名为XSCJ&#xff0c;表见附录A的登录表。2 创建Web项目命名为“Hibernate_Spring”3 添加Spring的开发能力右击项目名&#xff0c;选择【MyEclipse】→【A…

java 多进程多线程_Java并发编程原理与实战三:多线程与多进程的联系以及上下文切换所导致资源浪费问题...

一、进程考虑一个场景&#xff1a;浏览器&#xff0c;网易云音乐以及notepad 三个软件只能顺序执行是怎样一种场景呢&#xff1f;另外&#xff0c;假如有两个程序A和B&#xff0c;程序A在执行到一半的过程中&#xff0c;需要读取大量的数据输入(I/O操作)&#xff0c;而此时CPU只…

python用法查询笔记_Python爬虫学习笔记(三)

handler处理器自定义 - Cookies && URLError && json简单使用Cookies&#xff1a;以抓取https://www.yaozh.com/为例Test1(不使用cookies)&#xff1a;代码&#xff1a;import urllib.request# 1.添加URLurl "https://www.yaozh.com/"# 2.添加请求头…

java编程实现素数环_结对编程(JAVA实现)

项目成员&#xff1a;黄思扬(3117004657)、刘嘉媚(3217004685)二、PSP表格PSPPersonal Software Process Stages预估耗时(分钟)实际耗时(分钟)Planning计划6040 Estimate 估计这个任务需要多少时间6040Development开发14401505 Analysis 需求分析3015 Design Spec 生成设计文档…

java版的中世纪战争_世界战争英雄设置-火焰纹章英雄英雄地图及AI命令设置

英雄地图及AI命令设置游戏中练级塔中的AI设置和故事地图中的一样&#xff0c;所以如果故事地图中的AI是主动出击的&#xff0c;那练级塔一样的地图也是主动出击。故事地图中配置有5个敌人&#xff0c;在练级塔中也一样会配置5个敌人。不同的是职业可能会发生变化&#xff0c;但…

python pip安装依赖的常用软件源

目录 引言 一、什么是镜像源&#xff1f;​​​​​​​ 二、清华源 三、阿里源 四、中科大源 五、豆瓣源 六、更多资源 引言 在软件开发和使用过程中&#xff0c;我们经常需要下载和更新各种软件包和库文件。然而&#xff0c;由于网络环境的限制或者服务器的负载&#…

java虚拟机规范 51cto_java虚拟机

最近学习java虚拟机做了一些整理&#xff0c;会陆续发完。Java虚拟机一、概念&#xff1a;当我们谈到java虚拟机的时候&#xff0c;有可能指下面3个方面&#xff1a;1)&#xff1a;抽象java虚拟机的规范。2)&#xff1a;一个java虚拟机具体的实现。------实现是指&#xff1a;实…

ipv6+ssh+java_IPv6的本地联网地址计算方法详解

IPv6的世界里&#xff0c;如果DHCP6和SLACC这两位大佬都为没有为可怜的网卡分配IP地址&#xff0c;也没有人为网卡设置静态的IP地址&#xff0c;系统就会为网卡计算一个IPv6的网址来。这样的网址只能在本地使用&#xff0c;不得路由&#xff0c;所以&#xff0c;被称为“link-l…

java互斥锁的实现原理_java-深入分析synchronized原理

互斥锁互斥锁futex&#xff0c;全拼fast userspace mutexes&#xff0c;直翻为快速用户空间互斥器&#xff0c;它是我们上层应用实现锁的最常用方法。futex是一块所有进程都可以访问的内存&#xff0c;是通过cpu的原子操作修改内存中的值来尝试获取琐&#xff0c;如果没有竞争&…

京东开普勒php接口,IOS菜鸟初学第十五篇:接入京东开普勒sdk,呼起京东app打开任意京东的链接-Go语言中文社区...

我之前写了一篇关于接入京东联盟sdk的文章&#xff0c;但是最近&#xff0c;由于这个原因&#xff0c;如下图导致需要重新集成京东的sdk&#xff0c;但是由于某种原因&#xff0c;因为android和ios端不统一&#xff0c;android接入的是京东开普勒的SDK&#xff0c;这次为了统一…