基于.NetCore开发博客项目 StarBlog - (3) 模型设计
系列文章
- 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客?
- 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目
- 基于.NetCore开发博客项目 StarBlog - (3) 模型设计
- ...
- 基于.NetCore开发博客项目 StarBlog - 接口返回值包装
- 基于.NetCore开发博客项目 StarBlog - 上传图片功能
- 基于.NetCore开发博客项目 StarBlog - 身份认证功能
- 基于.NetCore开发博客项目 StarBlog - 前端相关
- 基于.NetCore开发博客项目 StarBlog - 前端开发 (1) 准备篇
- 基于.NetCore开发博客项目 StarBlog - 前端开发 (2) 页面路由
- 基于.NetCore开发博客项目 StarBlog - 前端开发 (3) SASS与SCSS
- 基于.NetCore开发博客项目 StarBlog - 前端开发 (4) FontAwesome图标
- 基于.NetCore开发博客项目 StarBlog - 前端开发 (5) Axios网络请求封装
- 基于.NetCore开发博客项目 StarBlog - 前端开发 (6) 登录页面
- 基于.NetCore开发博客项目 StarBlog - 前端开发 (7) 主页面
- 基于.NetCore开发博客项目 StarBlog - 前端开发 (8) Vuex与状态管理
- 基于.NetCore开发博客项目 StarBlog - 前端开发之文件上传
- 基于.NetCore开发博客项目 StarBlog - 前端开发之瀑布流图片列表
- 基于.NetCore开发博客项目 StarBlog - 前端开发之导航守卫
- ...
前言
上一篇文章介绍(水)了新建项目的操作,本文开始终于进入正题要开始写代码了!
对了,上一篇文章有朋友留言问管理端的用户名和密码是多少,这个是我疏忽了,没有做一个便捷的项目初始化功能,目前登录管理端需要在数据库的User表创建一个用户,后续我会完善角色和权限控制部分,然后给项目加一些命令行工具,就像django-admin
那样。
OK,本文介绍StarBlog博客项目的模型设计。
模型设计
根据博客的功能需求,数据分成三类:
- 文章相关(文章、文章分类)
- 摄影/相册相关
- 推荐内容配置(推荐文章、分类、图片;置顶文章、分类)
代码
由于我还没学DDD,(后续学了Abp vNext框架的话可能会用新技术进行重构),所以先用传统的MVC架构来规划项目~
回顾上一篇文章,我们新建了几个项目,现在,我们要把数据模型写在StarBlog.Data
项目中。
打开IDE,在StarBlog.Data
项目中新建一个目录,名为 Models
,接下来的数据模型全都要放到这个目录/命名空间下。
由于项目代码已经在GitHub开源了,数据模型代码我就不全部贴上来了,先看看创建完成之后的目录结构。
代码可以这里看到:https://github.com/Deali-Axy/StarBlog/tree/master/StarBlog.Data/Models
Models
├── Category.cs # 文章分类
├── FeaturedCategory.cs # 推荐分类
├── FeaturedPhoto.cs # 推荐图片
├── FeaturedPost.cs # 推荐文章
├── Photo.cs # 摄影图片
├── Post.cs # 文章
├── TopPost.cs # 置顶文章
└── User.cs # 用户
为了便于读者理解项目设计和模型间的关系,我们挑几个关键的说一下。
Category.cs
文章分类。完整代码见:https://github.com/Deali-Axy/StarBlog/blob/master/StarBlog.Data/Models/Category.cs
StarBlog博客支持markdown批量导入,然后以目录结构作为文章的分类,目录名就是分类名,且支持多级分类。
部分代码如下:
public class Category {
public int Id { get; set; }
public string Name { get; set; }
public int ParentId { get; set; }
public bool Visible { get; set; } = true;
}
Post.cs
完整代码见:https://github.com/Deali-Axy/StarBlog/blob/master/StarBlog.Data/Models/Post.cs
博客网站,最重要的就是文章,文章的模型部分代码如下
namespace StarBlog.Data.Models;
public class Post {
// 省略部分字段...
public string? Status { get; set; }
public bool IsPublish { get; set; }
public string? Path { get; set; }
public DateTime CreationTime { get; set; }
public DateTime LastUpdateTime { get; set; }
public string? Categories { get; set; }
}
首先看Status
和IsPublish
字段,一个是文章状态(未完成、未修改、未发布),一个是否发布。最终决定文章是否在网站上展示是IsPublish
字段,那Status
字段存在的意义是啥?
答案:为了保留导入前的文章状态。
本项目的博客支持导入整个目录markdown文件作为文章,我的习惯是会在markdown文件的文件名最前面写上这个文章的状态,比如一篇未完成的文章,它的文件名是:(未完成)StarBlog博客开发笔记(3):模型设计
,所以这个Status
字段就是要把(未完成)
中的这个状态识别提取出来,(具体用到的是正则表达式,这是后面要介绍的内容)。
然后是Path
字段,这个字段表示文章作为markdown文件导入前存放的相对位置,比如导入了D:\blog
这个目录里的所有文章,而这个目录的结构是这样的:
blog
├── Asp-Net-Core学习笔记
│ ├── Asp-Net-Core学习笔记:1.MVC入门篇.md
│ ├── Asp-Net-Core学习笔记:2.MVC视图、模型、持久化、文件、错误处理、日志.md
│ ├── Asp-Net-Core学习笔记:3.使用SignalR实时通信框架开发聊天室.md
│ ├── Asp-Net-Core学习笔记:4.Blazor-WebAssembly入门.md
│ ├── Asp-Net-Core学习笔记:5.构建和部署.md
│ ├── Asp-Net-Core学习笔记:WebApi开发实践.md
│ ├── Asp-Net-Core学习笔记:身份认证入门.md
│ ├── Asp-Net-Core学习笔记:部署,早知道,还是docker,以及一点碎碎念.md
├── Asp-Net-Core开发笔记
│ ├── Asp-Net-Core开发笔记:使用NPM和gulp管理前端静态文件.md
│ ├── Asp-Net-Core开发笔记:在docker部署时遇到一个小坑.md
│ └── Asp-Net-Core开发笔记:接口返回json对象出现套娃递归问题.md
├── 不吹不黑,跨平台框架AspNetCore开发实践杂谈.md
├── 梦想家装平台开发记录,Asp-Net-Core上手实践.md
├── (未修改)How-to-Connect-to-MySQL-from--NET-Core.md
├── (未修改)使用Ocelot实现Api网关.md
├── (未发布)跨域配置.md
├── (未完成)ASP-NET-Core-使用-Hangfire-定时任务.md
├── (未完成)Core-定时任务之HangFire.md
├── (未完成)使用-ASP-NET-Core-和-Hangfire-实现-HTTP-异步化方案.md
├── (未完成)使用Sentry.md
└── (未完成)在xunit里使用依赖注入.md
那对于在blog/AspNetCore
目录下的文章(未发布)跨域配置.md
来说,它的Path
字段就是AspNetCore
对于在blog/AspNetCore/Asp-Net-Core学习笔记
目录下的文章来说,Path
字段就是AspNetCore/Asp-Net-Core学习笔记
这个Path
字段的意义,就在于实现前面说的多级分类,同时最下面的Categories
字段,也是为了实现多级分类准备的。
在文章导入的过程中,目录名称作为文章分类名创建了文章的分类,同时记录分类ID到文章的CategoryId
字段中,如果是多级分类的话,文章的CategoryId
字段记录的是最后一个分类,父分类是不在这个CategoryId
里的,虽然Category
有个ParentId
字段可以找到父分类,但是在实际使用的时候比较麻烦,所以我又加了这个 Categories
字段,把文章的分类层级记录起来,其内容类似这样 1,2,3
,用逗号分隔开分类ID
这样前台展示的时候只需要用 services
把 Categories
字段处理成 List<Category>
就可以了。
Photo.cs
对了,还有图片模型,因为平时有空会拍照,所以做个摄影分享的功能,这个模型就存上传的图片。
部分代码如下
public class Photo {
// 省略部分字段...
public string Location { get; set; }
public string FilePath { get; set; }
public long Height { get; set; }
public long Width { get; set; }
}
图片的高度和宽度字段我一开始是没考虑的,不过在做瀑布流展示的时候发现没有宽高度不行,于是找到了 SixLabors.ImageSharp
这个库读取图片信息,这个库功能还挺强的,推荐一波~
Location
拍摄地点现在只能手动输入,我之前用Python做过一个相册的项目,可以根据图片的Exif信息读取拍摄的GPS信息,然后用逆地址解析的方法解析出拍摄的地址,这个先记个todo,后面来实现~
其他的
三个Featured开头的是推荐相关的,可以在后台配置;
然后置顶文章和置顶分类只能分别设置一个,展示在网站主页。
大概就这些了,下篇文章见~
同时所有项目代码已经上传GitHub,欢迎各位大佬Star/Fork!
- 博客后端+前台项目地址:https://github.com/Deali-Axy/StarBlog
- 管理后台前端项目地址:https://github.com/Deali-Axy/StarBlog-Admin
基于.NetCore开发博客项目 StarBlog - (3) 模型设计的更多相关文章
- 基于.NetCore开发博客项目 StarBlog - (4) markdown博客批量导入
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 基于.NetCore开发博客项目 StarBlog - (5) 开始搭建Web项目
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 基于.NetCore开发博客项目 StarBlog - (6) 页面开发之博客文章列表
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 基于.NetCore开发博客项目 StarBlog - (7) 页面开发之文章详情页面
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 基于.NetCore开发博客项目 StarBlog - (8) 分类层级结构展示
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 基于.NetCore开发博客项目 StarBlog - (9) 图片批量导入
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 基于.NetCore开发博客项目 StarBlog - (10) 图片瀑布流
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 基于.NetCore开发博客项目 StarBlog - (11) 实现访问统计
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 基于.NetCore开发博客项目 StarBlog - (12) Razor页面动态编译
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
随机推荐
- HTTP与HTTPS有什么区别
超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂 ...
- fiber核心(react 16)?
旧: 浏览器渲染引擎单线程, 计算DOM树时锁住整个线程, 所有行为同步发生, 有效率问题, 期间react会一直占用浏览器主线程,如果组件层级比较深,相应的堆栈也会很深,长时间占用浏览器主线程, 任 ...
- 什么是Java序列化,如何实现Java序列化?或者请解释Serializable接口的作用?
象序列化的目标是将对象保存到磁盘中,或允许在网络中直接传输对象,对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久保存在磁盘上,通过网络将这种二进制流传输到另 ...
- String s = new String("xyz");创建了几个String Object?
两个.一个是直接量的xyz对象:另一个是通过new Sting()构造器创建出来的String对象. 通常来说,应该尽量使用直接量的String对象,这样具有更好的性能.
- 什么是 Ribbon负载均衡?
(1)Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端 负载均衡的工具. (2)Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等.简单的说,就是在配 ...
- 四种类型的数据节点 Znode?
1.PERSISTENT-持久节点 除非手动删除,否则节点一直存在于 Zookeeper 上 2.EPHEMERAL-临时节点 临时节点的生命周期与客户端会话绑定,一旦客户端会话失效(客户端与 zoo ...
- docker打包镜像,测试部署
docker基本入门以后,(docker基本入门https://www.cnblogs.com/yangyangming/p/11470926.html)可以试试打包docker镜像与dockerfi ...
- 详细描述一下 Elasticsearch 索引文档的过程 ?
这里的索引文档应该理解为文档写入 ES,创建索引的过程. 文档写入包含:单文档写入和批量 bulk 写入,这里只解释一下:单文档写入流程. 记住官方文档中的这个图. 第一步:客户写集群某节点写入数据, ...
- Spring-MVC 里面的ModelAndView
作用: 由于本身http是无状态的并不会保存什么请求信息. 但是目标页面可能又需要一些信息.这时候可以用ModelAndView存放一些业务数据之类等.然后返回给页面 用法: 比较重要的方法: 往对 ...
- c++ 虚函数多态、纯虚函数、虚函数表指针、虚基类表指针详解
静态多态.动态多态 静态多态:程序在编译阶段就可以确定调用哪个函数.这种情况叫做静态多态.比如重载,编译器根据传递给函数的参数和函数名决定具体要使用哪一个函数.动态多态:在运行期间才可以确定最终调用的 ...