当前位置: 首页 >数据库 > EntityFramework Core 3.0查询

EntityFramework Core 3.0查询

前言

随着.NET Core 3.0的发布,EF Core 3.0也随之正式发布,关于这一块最近一段时间也没太多去关注,陆续会去对比之前版本有什么变化没有,本节我们来看下两个查询。

分组

我们知道在EF Core 3.0版本之前,对于分组查询是在客户端评估,也就是说在内存中操作,在EF Core 3.0版本后对于分组查询可以翻译成SQL在数据库进行,但是事实情况真的是这样吗?接下来我们来看下吧,如下给出代码例子。

public class EFCoreDbContext : DbContext{public EFCoreDbContext(){}public DbSet<Blog> Blogs { get; set; }public DbSet<Post> Posts { get; set; }protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)=> optionsBuilder.UseSqlServer(@"Server=.;Database=EFTest;Trusted_Connection=True;");}public class Blog{public int Id { get; set; }public string Name { get; set; }public List<Post> Posts { get; set; }}public class Post{public int Id { get; set; }public int BlogId { get; set; }public string Title { get; set; }public string Content { get; set; }public Blog Blog { get; set; }}

接下来我们在控制台进行如下查询:

var context = new EFCoreDbContext();var posts = context.Posts.GroupBy(d => d.BlogId).Select(g => new {id = g.Key,count = g.Count()}).ToList();

上述我们查询每一篇博客的文章数组,我们通过SQL Profiler跟踪到上述示例代码最终翻译成的SQL如我们所期望的那样,如下图:

EntityFramework Core 3.0查询 _ JavaClub全栈架构师技术笔记

假设现在有这样一个场景:查询所有博客发表的第一篇博客文章。基于这种场景我们需要对发表博客文章进行分组,然后取第一篇,所以接下来我们进行如下查询:

var context = new EFCoreDbContext();var posts = context.Posts.GroupBy(d => d.BlogId).Select(g => g.FirstOrDefault()).ToList();

EntityFramework Core 3.0查询 _ JavaClub全栈架构师技术笔记

既然这样无法翻译,根据官方文档可以使用Linq to Object进行查询《https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.0/》 ,那么我们就修改成如下代码查询看看:

var context = new EFCoreDbContext();var posts = context.Posts.GroupBy(d => d.BlogId).AsEnumerable().Select(d => d.FirstOrDefault()).ToList();

EntityFramework Core 3.0查询 _ JavaClub全栈架构师技术笔记

咋客户端都无法支持了呢?我们只是想查询所有博客列表中第一篇文章,按照我们的理解,理论上是可以进行翻译的对不对,比如翻译成如下直接写的SQL语句:

SELECT Id,BlogId,Title,Content FROM (  SELECT *  ,ROW_NUMBER() OVER ( PARTITION BY BlogId  ORDER BY Id) AS [ROW NUMBER]  FROM dbo.Posts  ) groupsWHERE groups.[ROW NUMBER] = 1ORDER BY groups.Id DESC

所以到这里我们大概可以猜测出EF Core对分组查询支持的并不是那么好,目前应该只支持简单的分组求和而已,稍微复杂一点则无法翻译,所以我们还是老老实实将分组还是完全放在客户端评估吧,如下:

var context = new EFCoreDbContext();var posts = context.Posts.ToList().GroupBy(d => d.BlogId).Select(d => d.FirstOrDefault()).ToList();

EntityFramework Core 3.0查询 _ JavaClub全栈架构师技术笔记 

查找

我们可以通过 EF.Functions.Like 来进行模糊查询,我们可以通过StartWith或EndWith来查询开头或结尾的数据,要是现在需要查询出博客文章标题中包含某一字符的文章列表,我们又该如何查询呢?我们想到通过IndexOf来查询,接下来我们来看看:

var context = new EFCoreDbContext();var posts = context.Posts.Where(d => d.Title.IndexOf('C') == 2).ToList();

EntityFramework Core 3.0查询 _ JavaClub全栈架构师技术笔记

难道我们又只能将所有查询出来,然后在内存中操作吗?代码如下:

var context = new EFCoreDbContext();var posts = context.Posts.ToList().Where(d => d.Title.IndexOf('C') == 2).ToList();

其实我们只要将上述单引号修改双引号即可解决完全在客户端评估的问题,如下:

var context = new EFCoreDbContext();var posts = context.Posts.Where(d => d.Title.IndexOf("C") == 2).ToList();

EntityFramework Core 3.0查询 _ JavaClub全栈架构师技术笔记

根据我们的查询描述,我们明明是想查询在标题中查询指定字符,为何对字符不能支持,只支持字符串呢,不知道官方是出于何种原因。同时这里我们也注意到,无论是MySQL还是SQL Server等等,尽量不要将表中列设置为可空,即使是可空也要设置为不可空,给定一个默认值即可,一旦数据量巨大时,会发现查询很慢,因为通过IS NULL或者IS NOT NULL不走索引导致。比如上述我们查询的Title,我们无论是通过Data Annotations还是Fluent Api,都必须配置成不可空,比如这里我们通过Data Annotations配置如下:

[Required]public string Title { get; set; }

此时我们继续进行上述查询时候,会发现对空值的判断已经没有了,同时也减少了查询语句,如下:

EntityFramework Core 3.0查询 _ JavaClub全栈架构师技术笔记

总结

请注意上述我所演示EF Core版本为3.0.1。本节我也只是通过简单的示例稍微给大家看了EF Core 3中一些小的问题,当然可能还存在其他的问题,更多细节等我后续研究会继续给出EF Core 3.x系列文章,感谢您的阅读,若有叙述不当或错误之处,还望指正,谢谢。

作者:Jeffcky
来源链接:https://www.cnblogs.com/CreateMyself/p/11968440.html

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。





本文链接:https://www.javaclub.cn/database/118451.html

标签:group by
分享给朋友:

“EntityFramework Core 3.0查询” 的相关文章

mysql 查询或 2022年06月07日 13:56:22
如何查看MySQL的版本? 2022年06月11日 22:08:01
查询mysql中user表 2022年06月12日 18:08:24
mysql的查询操作 2022年06月14日 12:38:40
mysql 去重查询 2022年06月15日 10:54:01
MySQl查询前三名(包括并列) 2022年06月17日 20:23:26
让MySQL查询的字段用中文显示 2022年06月20日 11:36:12
mysql获取上月月份 2022年06月21日 10:38:38