前言

当前开始学习ASP.Net Core,官方ORM EFCore不可不学,并且可以通过模型强约束字段是否编写正确,手写sql手残党福音

本文学习以CODE-FIRST的方式学习Entity Framework Core,主要包含配置模型(fluent API方式)、基本CRUE、迁移

配置模型

配置DBContext

1.创建DBContext

public class SystemInfoContext:DbContext
{
public SystemInfoContext(DbContextOptions<SystemInfoContext> options) : base(options)
{
}
}


2.注入相关配置,在​​Startup​​中,相关连接串和版本信息从​​appsettings.json​​中读取出来

public static void AddDbContexts(this IServiceCollection services)
{
services.AddDbContext<SystemInfoContext>(
options => options.UseMySql(Bootstrap.ConfigurationManager.DbConnectionString, new MySqlServerVersion(new Version(Bootstrap.ConfigurationManager.DbVersion))));
}


创建并配置模型

1.创建模型​​MenusEntity​

public class MenusEntity
{
public long m_id { get; set; }
public string m_name { get; set; }
public string m_code { get; set; }
public int m_level { get; set; }
public int m_parent_id { get; set; }
public string m_type { get; set; }
public int m_menu { get; set; }
public string m_page_url { get; set; }
public int m_status { get; set; }
public string m_icon { get; set; }
public int m_order { get; set; }
}


2.​​fluent API​​分组配置

public class MeunEntityTypeConfiguration : IEntityTypeConfiguration<MenusEntity>
{
public void Configure(EntityTypeBuilder<MenusEntity> builder)
{
//指定表名和备注
builder.ToTable("sys_menus").HasComment("菜单表");
//指定主键
builder.HasKey(t => t.m_id);
//自增
builder.Property(t => t.m_id).ValueGeneratedOnAdd();
builder.Property(t => t.m_id).HasMaxLength(10).IsRequired();
builder.Property(t => t.m_name).HasMaxLength(25).IsRequired();
builder.Property(t => t.m_code).HasMaxLength(10).IsRequired();
builder.Property(t => t.m_level).HasMaxLength(2).IsRequired();
builder.Property(t => t.m_parent_id).HasMaxLength(25).IsRequired();
builder.Property(t => t.m_type).HasMaxLength(1).IsRequired();
builder.Property(t => t.m_status).HasMaxLength(1).IsRequired();
//种子
builder.HasData(new MenusEntity {
m_id = 510,
m_name = "查询",
m_code = "G104",
m_level = 3,
m_parent_id = 0,
m_type = "P",
m_menu = 1,
m_page_url = "../list.html?type=search",
m_status = 1,
m_icon = "search-m",
m_order = 510
});
}
}


3.指定分组及仓储

public class SystemInfoContext:DbContext
{
public SystemInfoContext(DbContextOptions<SystemInfoContext> options) : base(options)
{
}
public DbSet<MenusEntity> Menus { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfiguration(new MeunEntityTypeConfiguration());
}
}


迁移

1.创建​​MigrationSystemInfoContext​​ 专门用于迁移

public class MigrationSystemInfoContext : SystemInfoContext
{
public MigrationSystemInfoContext(DbContextOptions<SystemInfoContext> options) : base(options)
{ }

public class CatalogContextDesignFactory : IDesignTimeDbContextFactory<MigrationSystemInfoContext>
{
public MigrationSystemInfoContext CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<SystemInfoContext>()
.UseMySql("server=localhost;user=root;password=root;database=zhao56", new MySqlServerVersion(new Version(8, 0, 25)));
return new MigrationSystemInfoContext(optionsBuilder.Options);
}
}
}


2.创建第一个迁移

Add-Migration []


执行

Add-Migration init
Add-Migration : Add-Migration cmdlet
:1 : 1
+ Add-Migration init
+ ~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Add-Migration:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException


安装包管理工具

Install-Package Microsoft.EntityFrameworkCore.Tools
#验证安装
PM> Get-Help about_EntityFrameworkCore

_/\__
---==/ \\
___ ___ |. \|\
| __|| __| | ) \\\
| _| | _| \_/ | //|\\
|___||_| / \\\/\\

TOPIC
about_EntityFrameworkCore


执行迁移命令

PM> Add-Migration init
Build started...
Build succeeded.
More than one DbContext was found. Specify which one to use. Use the '-Context' parameter for PowerShell commands and the '--context' parameter for dotnet commands.


指定​​context​

PM> Add-Migration init -Context MigrationSystemInfoContext
Build started...
Build succeeded.
To undo this action, use Remove-Migration.


此时发现多了个文件和文件如下图

ASP.NET Core之EF Core配置模型(fluent API方式)、基本CRUE、迁移的简单使用_bootstrap

并且后缀名为我们指定的名称

3.更新到数据库

PM> Update-Database -Context MigrationSystemInfoContext
Build started...
Build succeeded.
Applying migration '20210803055205_init'.
Done.


如下图:创建成功

ASP.NET Core之EF Core配置模型(fluent API方式)、基本CRUE、迁移的简单使用_bootstrap_02

基本CRUE

新建​​IMeunsRepositories​​ 接口 和​​MeunsRepositories​​实现类

public class MeunsRepositories : IMeunsRepositories
{
private readonly SystemInfoContext _context;
private DbSet<MenusEntity> _set => _context.Menus;
public MeunsRepositories(SystemInfoContext context)
{
this._context = context;
}

public async Task<long> AddMenusAsync(MenusEntity entity)
{
await _set.AddAsync(entity);
await _context.SaveChangesAsync();
return entity.m_id;
}

public async Task DelMenusAsync(long mId)
{
var menu = await _set.FirstOrDefaultAsync(t => t.m_id== mId);
_set.Remove(menu);
await _context.SaveChangesAsync();
}

public async Task<List<MenusEntity>> FindMenusListNoTrackingAsync(MenusEntity entity)
{
var query = _set.Where(k=>true);
if (entity != null)
{
if (!string.IsNullOrWhiteSpace(entity.m_name))
{
query = query.Where(k => k.m_name.Contains(entity.m_name));
}
if (entity.m_parent_id != 0)
{
query = query.Where(k => k.m_parent_id == entity.m_parent_id);
}
}
return await query.AsNoTracking().ToListAsync();
}

public async Task<List<MenusEntity>> FindMenusListTrackingAsync(MenusEntity entity)
{

var query = _set.Where(k => true);
if (entity != null)
{
if (!string.IsNullOrWhiteSpace(entity.m_name))
{
query = query.Where(k => k.m_name.Contains(entity.m_name));
}
if (entity.m_parent_id != 0)
{
query = query.Where(k => k.m_parent_id == entity.m_parent_id);
}
}
return await query.ToListAsync();
}

public async Task<MenusEntity> GetMenusAsync(long mId)
{
return await _set.FirstOrDefaultAsync(t => t.m_id == mId);
}

public async Task<List<MenusEntity>> MenusListAsync()
{
return await _set.AsNoTracking().ToListAsync();
}

public async Task<IPagedList<MenusEntity>> MenusPageListAsync(MenusEntity entity, Pager pager)
{
var query = _set.Where(k => true);
if (entity != null)
{
if (!string.IsNullOrWhiteSpace(entity.m_name))
{
query = query.Where(k => k.m_name.Contains(entity.m_name));
}
if (entity.m_parent_id != 0)
{
query = query.Where(k => k.m_parent_id == entity.m_parent_id);
}
}
return await query.OrderBy(k=>k.m_id).ToPageList(pager);
}

public async Task UpdateMenusAsync(long m_id, Action<MenusEntity> entityTrans)
{
var menu = await _set.FirstOrDefaultAsync(t => t.m_id == m_id);
entityTrans.Invoke(menu);
_set.Update(menu);
await _context.SaveChangesAsync();
}
}


说明:​​SystemInfoContext​​是通过构造函数注入进来的,声明周期交给了容器去处理

其他详细语法请参照官网