0%

IEnumerable与IQueryable 都能实现延迟加载的目的,但是两者之间还是有一些区别的,下面我们通过实际的代码来进行验证,创建一个控制台项目,数据库使用sqlite,EFCore操作数据库

创建项目

1
dotnet new console -o queryable_enumerable

添加sqlite EF操作的类库的引用:

1
2
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
dotnet add pacakge Microsoft.EntityFrameworkCore.Tools

还需要安装EF命令相关的类库

1
dotnet add package Microsoft.EntityFrameworkCore.Tools.DotNet

修改项目文件的内容如下:

image-20220426131129413

添加数据操作类

创建DBContext类库:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
internal class MyContext : DbContext
{
public static readonly ILoggerFactory MyLoggerFactory
= LoggerFactory.Create(builder =>
{
#if DEBUG
builder.AddConsole();
#endif
});
public DbSet<User> Users { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
//写完整地路径
string connString = @"Data Source=E:\xxx\xxx\xxx\xxx\queryable_enumerable\testdb.db";
optionsBuilder.UseSqlite(connString).UseLoggerFactory(MyLoggerFactory);
}
}

便于观察ef操作数据库的执行sql,这里将日志输出到控制台,需要引用类库Microsoft.Extensions.Logging.Console

1
dotnet add package Microsoft.Extensions.Logging.Console

添加 User实体类

1
2
3
4
5
6
7
internal class User
{
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[MaxLength(100), Required]
public string Name { get; set; }
}

执行EF命令,更新数据库

1
2
dotnet ef migrations add "InitialCreate"
dotnet ef database update

添加、获取数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// See https://aka.ms/new-console-template for more information
using queryable_enumerable;
using System.Text.Json;

Console.WriteLine("Hello, World!");

MyContext myContext = new();

//await myContext.Users.AddAsync(new User { Name = "sherman" });
//await myContext.SaveChangesAsync();

var users = myContext.Users.AsEnumerable().Where(p => p.Id > 0);

Console.WriteLine(JsonSerializer.Serialize(users));

var querable = myContext.Users.Where(p => p.Id > 0);

Console.WriteLine(JsonSerializer.Serialize(querable));

myContext.Dispose();

运行程序之后,可以看到如下的输出:

image-20220426132947167

从打印出的sql语句,我们可以知道,通过IEnumerable返回的数据,是一次性将所有的数据装入内存当中,然后进行过滤的操作,但是IQueryable是在数据库层就做了过滤,所以性能方面是有提升的。

问题现象,通过hexo创建完项目之后,通过typora编辑md文件,插入图片,本地开发是能显示图片的,但是发布到github上就显现不了,主要的原因肯定是路径的问题,hexo官网也给了解决的办法

资源文件夹

直接引用官网的解释:

资源(Asset)代表 source 文件夹中除了文章以外的所有文件,例如图片、CSS、JS 文件等。比方说,如果你的Hexo项目中只有少量图片,那最简单的方法就是将它们放在 source/images 文件夹中。然后通过类似于 ![](/images/image.jpg) 的方法访问它们。

对于那些想要更有规律地提供图片和其他资源以及想要将他们的资源分布在各个文章上的人来说,Hexo也提供了更组织化的方式来管理资源。这个稍微有些复杂但是管理资源非常方便的功能可以通过将 config.yml 文件中的 post_asset_folder 选项设为 true 来打开。

1
post_asset_folder: true

当资源文件管理功能打开后,Hexo将会在你每一次通过 hexo new [layout] <title> 命令创建新文章时自动创建一个文件夹。这个资源文件夹将会有与这个文章文件一样的名字。将所有与你的文章有关的资源放在这个关联文件夹中之后,你可以通过相对路径来引用它们,这样你就得到了一个更简单而且方便得多的工作流

相对路径引用的标签插件

通过常规的 markdown 语法和相对路径来引用图片和其它资源可能会导致它们在存档页或者主页上显示不正确。在Hexo 2时代,社区创建了很多插件来解决这个问题。但是,随着Hexo 3 的发布,许多新的标签插件被加入到了核心代码中。这使得你可以更简单地在文章中引用你的资源。

1
2
3
{% asset_path slug %}
{% asset_img slug [title] %}
{% asset_link slug [title] %}

比如说:当你打开文章资源文件夹功能后,你把一个 example.jpg 图片放在了你的资源文件夹中,如果通过使用相对路径的常规 markdown 语法 ![](example.jpg) ,它将 不会 出现在首页上。(但是它会在文章中按你期待的方式工作)

正确的引用图片方式是使用下列的标签插件而不是 markdown :

1
{% asset_img example.jpg This is an example image %}

通过这种方式,图片将会同时出现在文章和主页以及归档页中。

这种方式,在本地开发中不是太友好

在markdown文件中嵌入图片

首先引用 hexo-renderer-marked

1
npm install hexo-renderer-marked --save

然后修改_config.yml文件

1
2
3
4
post_asset_folder: true
marked:
prependRoot: true
postAsset: true

开启了之后,图片资源就会自动解析成对应的图片路径。比如:“test.jpg” 位于 “/2022/04/25/test/test.jpg”,

1
![](test.jpg)` 将会转换成 `<img src="/2022/04/25/test/test.jpg">

这种方式,虽然能解决发布之后图片展示的问题,但是不能解决本地typora编辑的问题,例如:有如下的目录结构:

image-20220425100849334

编辑hexo-github.md文件,如果写成:image-20220425100939907

这种相对路径之后,能在typora中显示图片,但是在网页上就不能展示图片,如果改成下面这种:

image-20220425101023160

能在网页上显示图片,但是在typora中又不能显示,这个时候,我们就通过修改插件 hexo-renderer-marked 的代码,来兼容两方的需求,找到图片路径转换的代码:

image-20220425101222552

其中红框中的代码就是新加的,这样我们在md文件中,路径写成:hexo-github/image-20220423232811690.png 这样,就能同时在typora和网页上进行展示,

1
2
3
hexo clean
hexo g
hexo s

查看没有问题

1
hexo d

最后发布到GitHub上,完美解决图片路径的问题。

Hexo环境搭建

  • Node.js (Node.js 版本需不低于 10.13,建议使用 Node.js 12.0 及以上版本)
  • Git
  • 安装hexo: npm install -g hexo-cli

完成上述操作之后,我们就可以通过hexo 命令创建项目

1
2
3
hexo init hexo_blog
cd hexo_blog
npm install

创建完成之后,可以看到我们的目录结构如下:

image-20220423232811690

其中_config.yml是网站的配置文件,关于各个文件夹是用来做什么的,可以参考hexo官方文档,其中有比较详细的介绍。接下,我们通过如下的命令运行该项目:

1
2
hexo g //生成静态文件
hexo s //启动服务

image-20220423233207440

服务已经成功启动,由于,默认的4000端口已经被占用,我就通过 hexo s -p 5000 指定了端口,然后在浏览器中输入:http://localhost:5000 可以看到运行的结果。

github pages

首先得要有GitHub的账号,然后创建一个项目

image-20220423233657056

创建完成之后,我们就可以通过https://likeshan168.com.cn进行访问,现在由于没有内容,所以会提示404,接下来我们就将hexo_blog发布到GitHub上

发布到GitHub

  • 安装hexo-deployer-git:npm install hexo-deployer-git –save

  • 修改_config.yml文件的deploy配置:

1
2
3
4
deploy:
type: 'git'
repository: https://github.com/likeshan168/likeshan168.com.cn.git
branch: master

如果在本地访问没有问题,部署到github pages查看样式都不对的话,修改_config.yml文件中的url=https://likeshan168.com.cn/(改成你自己项目的地址)

创建新页面

创建一个about me的页面:

1
hexo new page --path about/me "About me"

执行完命令之后就能看到在source目录下创建了about目录,about目录下多了me.md文件:
image-20220423235637325

添加菜单:

image-20220423235848764

重新生成一下静态文件

1
2
hexo g
hexo s

可以看到About的菜单生成了

image-20220423235939551

最后,将我们的修改推送到GitHub上即可

1
hexo d

刷新https://likeshan168.com.cn就可以看到我们的更新,至此,通过hexo+github pages进行博客系统的搭建基本已经讲完,关于hexo比较详细的操作流程,还需参考官网,谢谢。