【温故知新】C#中 IEnumerable 与IQueryable
微信公众号:趣编程ACE
关注可了解更多的.NET日常实战开发技巧,如需源码 后台回复 源码 即可;
如果觉得对你有帮助,欢迎关注
老生常谈 C#中 IEnumerable 与IQueryable
IEnumerable 与 IQueryable 对于.Neter来说并不陌生,今天我就着重阐述下两者加载方式的异同。
前文回顾
【温故知新】C# Linq中 Select && SelectMany 使用技巧
IEnumerable<T>
1.接口位于命名空间System.Collections中,是可以使用foreach进行枚举集合的基接口
2.里面有一个GetEnumeartor()方法用来迭代集合,不是线程安全的 调用MoveNext()来顺序读取下一个集合中对象
3.不支持在集合上添加、删除对象
4.支持延迟执行,主要是yield 关键字
5.不支持延迟加载,不适用于分页场景
6.读取数据库或者服务数据时,IEnumerable将所有数据查询出放置内存中,然后再进行相应筛选操作
7.对于内存中的数据,我们使用IEnumerable来操作
好了,那我们通过代码来演示下IEnumerable为啥不在服务端进行过滤筛选操作?
新建一个基于.net6的控制台程序
2.安装SqlLite的EFCore依赖包
1Install-Package Microsoft.EntityFrameworkCore.Sqlite
3.创建实体
1public class BloggingContext : DbContext2{3 public DbSet<Blog> Blogs { get; set; }4 public DbSet<Post> Posts { get; set; }56 public string DbPath { get; }78 public BloggingContext()9 {
10 var folder = Environment.SpecialFolder.LocalApplicationData;
11 var path = Environment.GetFolderPath(folder);
12 DbPath = System.IO.Path.Join(path, "blogging.db");
13 }
14
15 // The following configures EF to create a Sqlite database file in the
16 // special "local" folder for your platform.
17 protected override void OnConfiguring(DbContextOptionsBuilder options)
18 => options.UseSqlite($"Data Source={DbPath}");
19}
20
21public class Blog
22{
23 public int BlogId { get; set; }
24 public string Url { get; set; }
25
26 public List<Post> Posts { get; } = new();
27}
28
29public class Post
30{
31 public int PostId { get; set; }
32 public string Title { get; set; }
33 public string Content { get; set; }
34
35 public int BlogId { get; set; }
36 public Blog Blog { get; set; }
37}
4.创建数据库
1Install-Package Microsoft.EntityFrameworkCore.Tools
2Add-Migration InitialCreate
3Update-Database
5.对数据库进行插入和读取操作
1using System;2using System.Linq;34using var db = new BloggingContext();56Console.WriteLine($"数据库路径: {db.DbPath}.");78// Create9Console.WriteLine("Inserting a new blog");
10db.Add(new Blog { Url = "http://blogs.msdn.com/adonet" });
11db.SaveChanges();
12
13// Read
14Console.WriteLine("Querying for a blog");
15IEnumerable<Blog> blog = db.Blogs;
16
17var data = blog.
18 Where(b => b.Url == "http://blogs.msdn.com/adonet").Take(2);
19
20foreach (var item in data)
21{
22 Console.WriteLine(item);
23}
6.为项目集成日志
一、建立一个ConsoleLogger日志类并继承ILogger接口
public IDisposable BeginScope<TState>(TState state)2{3 return null;4}56public bool IsEnabled(LogLevel logLevel)7{8 switch (logLevel)9 {
10 case LogLevel.Trace:
11 case LogLevel.Information:
12 case LogLevel.None:
13 return false;
14 case LogLevel.Debug:
15 case LogLevel.Warning:
16 case LogLevel.Error:
17 case LogLevel.Critical:
18 default:
19 return true;
20 }
21}
22
23public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
24{
25 Console.WriteLine($"Level:{logLevel},EventId:{eventId.Id},EventName:{eventId.Name}");
26 if(state !=null)
27 {
28 Console.WriteLine($"State:{state}");
29 }
30
31 if(exception!=null)
32 {
33 Console.WriteLine($"Exception:{exception.Message}");
34 }
35}
二、创建一个ConsoleLoggerProvider类并继承ILoggerProvider接口
1public class ConsoleLoggerProvider : ILoggerProvider2{3 public ILogger CreateLogger(string categoryName)4 {5 return new ConsoleLogger();6 }78 public void Dispose()9 {
10
11 }
12}
三、控制台引入日志服务
1var loggerFactory=db.GetService<ILoggerFactory>();
2loggerFactory.AddProvider(new ConsoleLoggerProvider());
通过上图箭头指向的控制台输出的sql语句,可以显然的看见IEnumerable在查询数据库是只进行了 select * from 操作,并没有在数据库里面进行我们相应的过滤操作,而是将所有的数据一窝蜂查出来然后灌入内存中,最后在内存中进行过滤操作。
那么我们将db.Blogs 改为IQueryable类型呢
1IQueryable<Blog> blog = db.Blogs;
很明显可以看出,IQueryable将语句转为了我们需要的sql,因为IQueryable接受一个表达式树,表达式树将我们语句拼接,最后转化为查询sql,就实现了在数据库层次的过滤筛选。
IQueryable
1.IQueryable 位于System.Linq命名空间
2.IQueryable 支持延迟执行
3.IQueryable 支持延迟加载,因此适用于类分页的场景。
4.本身也是扩展自IEnumerable
【温故知新】C#中 IEnumerable 与IQueryable相关推荐
- EntityFramework中IEnumerable和IQueryable的含义和区别
先说下IList,IList对SQL语句是即时执行的,IEnumerable和IQueryable是延时执行的,用到才执行. IQueryable和IEnumerable在每次执行时都必须连接数据库读 ...
- IEnumerable和IQueryable在使用时的区别
最近在调研数据库查询时因使用IEnumerable进行Linq to entity的操作,造成数据库访问缓慢.此文讲述的便是IEnumerable和IQueryable的区别. 微软对IEnumera ...
- Entity Framework返回IEnumerable还是IQueryable?
在使用EF的过程中,我们常常使用repository模式,本文就在repository层的返回值是IEnumerable类型还是IQueryable进行探讨. 阅读目录: 一.什么是Repositor ...
- 一个简单问题引发对IEnumerable和IQueryable的思考
问题概述: 首先看下图,有客户表和客户负责人表关系是多对多,访问数据库使用的是EF所以这里我们开启了延迟加载,需求就是将每个客户的所有负责人逗号拼接显示在负责人这一栏位, 对你没看错需求就是这么 ...
- IEnumerable和IQueryable的区别以及背后的ExpressionTree表达式树
关于IEnumerable和IQueryable的区别,这事还要从泛型委托Func<T>说起.来看一个简单的泛型委托例子: class Program { static void Main ...
- IEnumerable与IQueryable
共有两组 LINQ 标准查询运算符,一组在类型为 IEnumerable<T> 的对象上运行,另一组在类型为 IQueryable<T>的对象上运行.构成每组运算符的方法分别是 ...
- EF Core:基于关系的复杂查询 区分IEnumerable和IQueryable
基于关系的复杂查询 表结构描述:一个文章带有多个评论,现在想输出所有,评论中带"微软"的文章.换句话说开,只要这个文章中的评论带这个词,就放入集合中去. 基于EF Core的实体间 ...
- IEnumerable和IQueryable的区别
IEnumerable<T>在.Net2.0中我们已经很熟悉了.你想要利用Foreach迭代吗?实现 IEnumerable<T>吧!你想直接做为数据源绑定到控件吗?使用IEn ...
- 最全数据结构详述: List VS IEnumerable VS IQueryable VS ICollection VS IDictionary
本文对常用的数据结构详述:Array, ArrayList,List,IList,ICollection, Stack, Queue, HashTable, Dictionary, IQueryabl ...
最新文章
- 吴恩达机器学习入门 2018 高清视频公开,还有习题解答和课程拓展,网友:找不到理由不学!...
- 手把手教你安装OpenStack——Ocata安装指南(上)
- java web利用mvc结构实现简单聊天室功能
- 东大19春在线作业计算机应用基础,东大19春学期《计算机应用基础》在线作业2...
- 陈桥五笔用户编号获取_用户群组分析
- Visual.Assist.X 菜单汉化
- 自动化测试---Assert
- mysql java 社工库_社工库源码
- Java Tricks —— 不小于一个数的最小2的幂次方
- 全网最全Linux常用命令
- vue 中引入使用其他字体
- 使用第三方应用友盟实现网站访问量统计功能
- 四维空间的二维线框投影可视化(附matlab代码)
- 什么是法?什么是僧?
- Codeforces 并查集题集(Disjoint Sets Union Step1)
- logback使用及详解
- Python撩妹实战——教你用微信每天给女朋友说晚安
- 机器学习(四):剪枝技术(基础篇)
- poj 1689 zoj 1422 3002 Rubbery (Geometry + BFS)
- MSRA显著性检测数据集