基于Asp.Net Core3.1项目实战之Entity层实现
前言
为方便开发,项目采用CodeFirst的方式来快速更新数据库结构,如果对CodeFirst不熟悉的可以查看官方文档及示例。另外此项目所有新建的文件全部是在Diary.Entity层。
需求梳理
此项目为日记系统,大体功能与初期项目一致。主要功能有:
- 用户登录注册
- 日记分类
- 日记发布
- 评论功能
实体定义
首先我们先在Entity项目中定义一个BaseEntity,将所有Entity将会出现的字段放置其中,然后其他Entity全部继承它。
using System;
using System.ComponentModel.DataAnnotations;
namespace Diary.Entity
{
public class BaseEntity
{
[Key]
public Guid Id { get; set; } = Guid.NewGuid();
public DateTime CreateTime { get; set; } = DateTime.Now;
public bool IsRemove { get; set; }
}
}
这里用户我们采用Guid来实现,然后所有的删除采用的是软删除,也就是所有数据的展示与否全部由IsRemove字段来控制。
用户实体
using System.ComponentModel.DataAnnotations;
namespace Diary.Entity
{
public class User : BaseEntity
{
[Required, StringLength(40)]
public string Email { get; set; }
[Required, StringLength(30)]
public string Password { get; set; }
[Required, StringLength(300)]
public string AvatarPath { get; set; }
public int FansCount { get; set; }
public int FocusCount { get; set; }
}
}
分类实体
using System.ComponentModel.DataAnnotations;
namespace Diary.Entity
{
public class Category : BaseEntity
{
[Required, StringLength(100)]
public string Title { get; set; }
}
}
日记实体
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Diary.Entity
{
public class DiaryEntity : BaseEntity
{
[Required,StringLength(100)]
public string Title { get; set; }
[Required, MaxLength(2000)]
public string Content { get; set; }
[ForeignKey(nameof(User))]
public Guid UserId { get; set; }
public User User { get; set; }
/// <summary>
/// 点赞数量
/// </summary>
public int GoodCount { get; set; }
/// <summary>
/// 反对数量
/// </summary>
public int BadCount { get; set; }
public int FollowCount { get; set; }
[Required]
public bool IsPublic { get; set; }
[ForeignKey(nameof(Category))]
public Guid CategoryId { get; set; }
public Category Category { get; set; }
}
}
评论实体
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Diary.Entity
{
public class Comment : BaseEntity
{
[Required, MaxLength(2000)]
public string Content { get; set; }
[ForeignKey(nameof(User))]
public Guid CreateId { get; set; }
public User Creater { get; set; }
[ForeignKey(nameof(Diary))]
public Guid DiaryId { get; set; }
public DiaryEntity Diary { get; set; }
}
}
DbContext配置
DbSet配置
新建DiaryContext文件,具体代码如下所示,其中OnModelCreating中所调用的方法会在ModelBuilder 配置
中讲到。
using Diary.Entity.ModelBuilds;
using Microsoft.EntityFrameworkCore;
namespace Diary.Entity
{
public class DiaryContext : DbContext
{
public DiaryContext(DbContextOptions options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
new DiaryBuilder(builder);
new CommentBuilder(builder);
}
public DbSet<DiaryEntity> Diaries { get; set; }
public DbSet<User> Users { get; set; }
public DbSet<Category> Categories { get; set; }
public DbSet<Comment> Comments { get; set; }
}
}
ModelBuilder 配置
自定义配置,主要是指定表之间关联关系,在Entity项目中新建一个ModelBuilds文件夹,将所有的Builder类全部放置此文件夹中。
DiaryBuilder
using Microsoft.EntityFrameworkCore;
namespace Diary.Entity.ModelBuilds
{
public class DiaryBuilder
{
public DiaryBuilder(ModelBuilder builder)
{
var diary = builder.Entity<DiaryEntity>();
diary.HasKey(p => p.Id);
diary.HasOne(p => p.User)
.WithMany()
.HasForeignKey(p => p.UserId)
.OnDelete(DeleteBehavior.NoAction);
diary.HasOne(p => p.Category)
.WithMany()
.HasForeignKey(p => p.CategoryId)
.OnDelete(DeleteBehavior.NoAction);
}
}
}
CommentBuilder
using Microsoft.EntityFrameworkCore;
namespace Diary.Entity.ModelBuilds
{
public class CommentBuilder
{
public CommentBuilder(ModelBuilder builder)
{
var commentBuilder = builder.Entity<Comment>();
commentBuilder.HasKey(p => p.Id);
commentBuilder
.HasOne(p => p.Creater)
.WithMany()
.HasForeignKey(p => p.CreateId)
.OnDelete(DeleteBehavior.NoAction);
commentBuilder
.HasOne(p => p.Diary)
.WithMany()
.HasForeignKey(p => p.CreateId)
.OnDelete(DeleteBehavior.NoAction);
}
}
}
数据库配置
1.首先打开Diary,右键点击依赖项,然后勾选所有项目,操作如下所示。
2.然后配置数据连接字符串,由于这里是开发环境,我们可以打开appsettings.Development,在其中加入连接字符串,完整配置如下。
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"SqlServerConnection": "Server=.;Database=diary;User ID=sa;Password=YourPassword;"
}
}
- 为整个项目配置所使用的数据库,在Startup.cs 中ConfigureServices配置,加入如下代码。
services.AddDbContext<DiaryContext>(options =>
{
//o.UseInMemoryDatabase("Demo")
//options.UseMySQL(Configuration.GetConnectionString("MysqlSqlServerConnection"),
// p => p.MigrationsAssembly("Diary.Entity"));
options.UseSqlServer(Configuration.GetConnectionString("SqlServerConnection"),
p => p.MigrationsAssembly("Diary.Entity"));
}, ServiceLifetime.Scoped);
4. 通过CodeFirst生成数据库
打开程序包管理器控制台,选择默认项目为Diary.Entity,然后就可以开始使用以下CodeFirst命令来更新数据库。InitDb为命名,你可以随意取名,在运行完命令之后就会在Entity项目中出现Migrations文件夹,里面所存放的就是你的迁移记录。
add-migration InitDb
update-database
我这里应为已经迁移成功了,下面显示的是To undo this action, use Remove-Migration.
并且没有再去执行update-database
命令。
最终效果
最终Entity层的文件结构如下所示。
数据库结果如下图所示