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

前言

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

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

官方地址:https://docs.microsoft.com/zh-cn/ef/core/managing-schemas/migrations/?tabs=vs

配置模型

配置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.

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

image

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

3.更新到数据库

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

如下图:创建成功

image

基本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是通过构造函数注入进来的,声明周期交给了容器去处理

其他详细语法请参照官网

posted @ 2021-08-03 14:03  zhao56  阅读(358)  评论(0编辑  收藏  举报