第2章 抽离表及其字段的约束规则定义
创始人
2024-04-26 20:54:17
0

1 表及其字段的约束规则定义

1.1 Data.Mapping.Users.RoleBuilder

//Nuget

//Nuget--Microsoft.EntityFrameworkCore.SqlServer

using Microsoft.EntityFrameworkCore;

using Microsoft.EntityFrameworkCore.Metadata.Builders;

//项目

using Core.Domain.Users;

namespace Data.Mapping.Users

{

    ///

    /// 【角色生成器--类】

    ///

    /// 摘要:

    ///     该类通过对“EntityFrameworkCore”中间件“IEntityTypeConfiguration<>”泛型接口的“Configure”方法的定义,以实现把角色实体类及其属性成员相关约束规则及其级联关系定义,映射到角色表及其的相应字段上。

    ///

    ///

    public class RoleBuilder : IEntityTypeConfiguration

    {

        #region 方法--IEntityTypeConfiguration<>

        ///实体类型生成器实例,用于把当前程序中指定实体和属性所定义的约束规则,映射到数据库指定表及其字段上。

        ///

        /// 【配置】

        ///

        /// 摘要:

        ///     该方法通过对“EntityFrameworkCore”中间件“IEntityTypeConfiguration<>”泛型接口的“Configure”方法的定义,以实现把角色实体类及其属性成员相关约束规则及其级联关系定义,映射到角色表及其的相应字段上。

        ///

        ///

        public void Configure(EntityTypeBuilder builder)

        {

            //由于“EntityTypeBuilder”的参数已经泛型实例化,因此builder后不能再定义为:“builder.Entity().HasKey(role => role.Id);”。

            //角色表及其字段约束规则,映射定义。

            builder.HasKey(role => role.Id);

            builder.Property(role => role.Name).IsRequired().HasMaxLength(255);

        }

        #endregion

    }

}

1.2 Data.Mapping.Users.UserBuilder

//Nuget

//Nuget--Microsoft.EntityFrameworkCore.SqlServer

using Microsoft.EntityFrameworkCore;

using Microsoft.EntityFrameworkCore.Metadata.Builders;

//项目

using Core.Domain.Users;

namespace Data.Mapping.Users

{

    ///

    /// 【用户生成器--类】

    ///

    /// 摘要:

    ///     该类通过对“EntityFrameworkCore”中间件“IEntityTypeConfiguration<>”泛型接口的“Configure”方法的定义,以实现把用户实体类及其属性成员相关约束规则及其级联关系定义,映射到用户表及其的相应字段上。

    ///

    ///

    public class UserBuilder : IEntityTypeConfiguration

    {

        #region 方法--IEntityTypeConfiguration<>

        ///实体类型生成器实例,用于把当前程序中指定实体和属性所定义的约束规则,映射到数据库指定表及其字段上。

        ///

        /// 【配置】

        ///

        /// 摘要:

        ///     该方法通过对“EntityFrameworkCore”中间件“IEntityTypeConfiguration<>”泛型接口的“Configure”方法的定义,以实现把用户实体类及其属性成员相关约束规则及其级联关系定义,映射到用户表及其的相应字段上。

        ///

        ///

        public void Configure(EntityTypeBuilder builder)

        {

            //由于“EntityTypeBuilder”的参数已经泛型实例化,因此builder后不能再定义为:“builder.Entity().HasKey(user => user.Id);”。

            //用户表及其字段约束规则,映射定义。

            builder.HasKey(user => user.Id);

            builder.Property(user => user.Name).IsRequired().HasMaxLength(255);

            builder.Property(user => user.Email).IsRequired().HasMaxLength(255);

            builder.Property(user => user.Password).IsRequired().HasMaxLength(255);

            builder.Property(user => user.Phone).HasMaxLength(50);

            builder.Property(user => user.RememberToken).HasMaxLength(500);

            builder.Property(user => user.Avatar).HasMaxLength(255);

            builder.Property(user => user.CreatedDateTime).IsRequired();

            builder.Property(user => user.UpdatedDateTime).IsRequired();

            builder.Ignore(user => user.RoleCollection);

        }

        #endregion

    }

}

1.3 Data.Mapping.Users.UserRoleBuilder

//Nuget

//Nuget--Microsoft.EntityFrameworkCore.SqlServer

using Microsoft.EntityFrameworkCore;

using Microsoft.EntityFrameworkCore.Metadata.Builders;

//项目

using Core.Domain.Users;

namespace Data.Mapping.Users

{

    ///

    /// 【用户角色映射生成器--类】

    ///

    /// 摘要:

    ///     该类通过对“EntityFrameworkCore”中间件“IEntityTypeConfiguration<>”泛型接口的“Configure”方法的定义,以实现把用户角色映射实体类及其属性成员相关约束规则及其级联关系定义,映射到用户角色映射表及其的相应字段上。

    ///

    ///

    public class UserRoleBuilder : IEntityTypeConfiguration

    {

        #region 方法--IEntityTypeConfiguration<>

        ///实体类型生成器实例,用于把当前程序中指定实体和属性所定义的约束规则,映射到数据库指定表及其字段上。

        ///

        /// 【配置】

        ///

        /// 摘要:

        ///     该方法通过对“EntityFrameworkCore”中间件“IEntityTypeConfiguration<>”泛型接口的“Configure”方法的定义,以实现把用户角色映射实体类及其属性成员相关约束规则及其级联关系定义,映射到用户角色映射表及其的相应字段上。

        ///

        ///

        public void Configure(EntityTypeBuilder builder)

        {

            //由于“EntityTypeBuilder”的参数已经泛型实例化,因此builder后不能再定义为:“builder.Entity().HasKey(userRole => new { userRole.UserId, userRole.RoleId });”。

            //用户角色映射表及其字段约束规则,映射定义。

            builder.HasKey(userRole => new { userRole.UserId, userRole.RoleId });

            builder.HasOne(userRole => userRole.UserSingle)

                .WithMany(user => user.UserRoleCollection)

                .HasForeignKey(userRole => userRole.UserId)

                .IsRequired();

            builder.HasOne(userRole => userRole.RoleSingle)

                .WithMany()

                .HasForeignKey(userRole => userRole.RoleId)

                .IsRequired();

            builder.Ignore(userRole => userRole.Id);

        }

        #endregion

    }

}

1.4 Data.Mapping.Security.PermissionBuilder

//Nuget

//Nuget--Microsoft.EntityFrameworkCore.SqlServer

using Microsoft.EntityFrameworkCore;

using Microsoft.EntityFrameworkCore.Metadata.Builders;

//项目

using Core.Domain.Security;

namespace Data.Mapping.Security

{

    ///

    /// 【权限生成器--类】

    ///

    /// 摘要:

    ///     该类通过对“EntityFrameworkCore”中间件“IEntityTypeConfiguration<>”泛型接口的“Configure”方法的定义,以实现把权限实体类及其属性成员相关约束规则及其级联关系定义,映射到权限表及其的相应字段上。

    ///

    ///

    public class PermissionBuilder : IEntityTypeConfiguration

    {

        #region 方法--IEntityTypeConfiguration<>

        ///实体类型生成器实例,用于把当前程序中指定实体和属性所定义的约束规则,映射到数据库指定表及其字段上。

        ///

        /// 【配置】

        ///

        /// 摘要:

        ///     该方法通过对“EntityFrameworkCore”中间件“IEntityTypeConfiguration<>”泛型接口的“Configure”方法的定义,以实现把权限实体类及其属性成员相关约束规则及其级联关系定义,映射到权限表及其的相应字段上。

        ///

        ///

        public void Configure(EntityTypeBuilder builder)

        {

            //由于“EntityTypeBuilder”的参数已经泛型实例化,因此builder后不能再定义为:“builder.Entity().HasKey(permission => permission.Id);”。

            //权限表及其字段约束规则,映射定义。

            builder.HasKey(permission => permission.Id);

            builder.Property(permission => permission.Name).IsRequired().HasMaxLength(255);

            builder.Property(permission => permission.Category).IsRequired().HasMaxLength(500);

        }

        #endregion

    }

}

1.5 Data.Mapping.Security.PermissionRoleBuilder

//Nuget

//Nuget--Microsoft.EntityFrameworkCore.SqlServer

using Microsoft.EntityFrameworkCore;

using Microsoft.EntityFrameworkCore.Metadata.Builders;

//项目

using Core.Domain.Security;

namespace Data.Mapping.Security

{

    ///

    /// 【权限角色映射生成器--类】

    ///

    /// 摘要:

    ///     该类通过对“EntityFrameworkCore”中间件“IEntityTypeConfiguration<>”泛型接口的“Configure”方法的定义,以实现把权限角色映射实体类及其属性成员相关约束规则及其级联关系定义,映射到权限角色映射表及其的相应字段上。

    ///

    ///

    public class PermissionRoleBuilder : IEntityTypeConfiguration

    {

        #region 方法--IEntityTypeConfiguration<>

        ///实体类型生成器实例,用于把当前程序中指定实体和属性所定义的约束规则,映射到数据库指定表及其字段上。

        ///

        /// 【配置】

        ///

        /// 摘要:

        ///     该方法通过对“EntityFrameworkCore”中间件“IEntityTypeConfiguration<>”泛型接口的“Configure”方法的定义,以实现把权限角色映射实体类及其属性成员相关约束规则及其级联关系定义,映射到权限角色映射表及其的相应字段上。

        ///

        ///

        public void Configure(EntityTypeBuilder builder)

        {

            //由于“EntityTypeBuilder”的参数已经泛型实例化,因此builder后不能再定义为:“builder.Entity().HasKey(permissionRole => new { permissionRole.PermissionId, permissionRole.RoleId });”。

            //权限角色映射表及其字段约束规则,映射定义。

            builder.HasKey(permissionRole => new { permissionRole.PermissionId, permissionRole.RoleId });

            builder.HasOne(permissionRole => permissionRole.PermissionSingle)

                .WithMany(permission => permission.PermissionRoleCollection)

                .HasForeignKey(permissionRole => permissionRole.PermissionId)

                .IsRequired();

            builder.HasOne(permissionRole => permissionRole.RoleSingle)

                .WithMany(role => role.PermissionRoleCollection)

                .HasForeignKey(permissionRole => permissionRole.RoleId)

                .IsRequired();

            builder.Ignore(permissionRole => permissionRole.Id);

        }

        #endregion

    }

}

2 重构Data.EFCoreContext

//Nuget

//Nuget--Microsoft.EntityFrameworkCore.SqlServer

using Microsoft.EntityFrameworkCore;

//项目

using Core.Domain;

using System.Reflection;

namespace Data

{

    ///

    /// 【EFCore上下文】

    ///

    /// 摘要:

    ///     基类构造方法通过该类构造方法中的参数实例,实例化了“Microsoft.EntityFrameworkCore.SqlServer”中间件,

    /// 以实现“Microsoft.EntityFrameworkCore.SqlServer”中间件与指定数据库(SQL Server)数据库软件中的指定数据库的连接,

    /// 最终达到实体与相应表之间通过“Microsoft.EntityFrameworkCore.SqlServer”中间件进行CURD的交互操作的目的(功能)。

    ///

    ///

    public class EFCoreContext : DbContext

    {

        #region 拷贝构造方法

        ///配置参数实例,通过配置参数实例,调用基类的拷贝构造方法以实现“Microsoft.EntityFrameworkCore.SqlServer”中间件与(SQL Server)数据库软件中指定数据库的连接。

        ///

        /// 【拷贝构造方法】

        ///

        /// 摘要:

        ///    基类构造方法通过该类构造方法中的参数实例,实例化了“Microsoft.EntityFrameworkCore.SqlServer”中间件,

        /// 以实现“Microsoft.EntityFrameworkCore.SqlServer”中间件与指定数据库(SQL Server)数据库软件中的指定数据库的连接,

        /// 最终达到实体与相应表之间通过“Microsoft.EntityFrameworkCore.SqlServer”中间件进行CURD的交互操作的目的(功能)。

        ///

        ///

        public EFCoreContext(DbContextOptions options) : base(options)

        {

            //如果(SQL Server)数据库软件中没有指定的数据库, 当通过Code First模式时,在第1次生成数据库时,则通过下1行语句结合数据库连接字符串,在(SQL Server)数据库软件中生成指定的数据库数据库、表和字段。

            Database.EnsureCreated();

            /*

            如果(SQL Server)数据库软件中没有指定的数据库, 当通过Code First模式时,在第1次生成数据库时,则也通过下行执行迁移和更新命令行的结合数据库连接字符串,在(SQL Server)数据库软件中生成指定的数据库数据库、表和字段。

            Add-Migration Initialize(Initialize:自动生成的迁移类名,这里特指:20220803125612_Initialize.cs):

            Update-Database Initialize(通过自动生成的迁移类中的定义,自动在指定的数据库软件中生成指定的数据库、表、字段和约束规则)

             */

        }

        #endregion

        #region 虚方法

        ///泛型类型实例(这里限定了于“BaseEntity”抽象类的实体类的类型实例)。

        ///

        /// 【获取数据库设置】

        ///

        /// 摘要:

        ///     该方法通过泛型方式获取1个指定实体的数据库设置实例(DbSet),以实现指定实体与指定表之间的CURD的交互操作,并把这些数据存储到数据库设置实例中(内存)。

        ///

        ///

        /// 返回:

        ///     1个指定实体的数据库设置实例(DbSet),以实现指定实体与指定表之间的CURD的交互操作,并把这些数据存储到数据库设置实例中(内存)。

        ///

        ///

        public virtual DbSet GetDbSet() where TEntity : BaseEntity

        {

            return base.Set();

        }

        #endregion

        #region 方法--私有/保护--覆写

        ///模型生成器实例,用于把当前程序中实体和属性所定义的约束规则,映射到数据库指定表及其字段上。

        ///

        /// 【模型生成执行...】

        ///

        /// 摘要:

        ///     该方法把当前程序中实体和属性所定义的约束规则,映射到数据库指定表及其字段上。

        ///

        ///

        protected override void OnModelCreating(ModelBuilder builder)

        {

            //EntityFrameworkCore <= 2.1或EntityFrameworkCore <= 2.1~EntityFrameworkCore = 7.0.1(至今)。

            //通过反射方式把“Data”项目中所有继承“IEntityTypeConfiguration<>”泛型接口的表及其字段约束规则定义类进行实现化操作,

            //优点:有过滤操作,只获取继承“IEntityTypeConfiguration<>”泛型接口的具体实现类。

            //缺点:没有下述方式简单。

            //List _typeBuilderList = Assembly.GetExecutingAssembly().GetTypes()

            //    .Where(t => t.GetInterfaces().Any(gi => gi.IsGenericType && gi.GetGenericTypeDefinition() == typeof(IEntityTypeConfiguration<>)))

            //    .ToList();

            //foreach (var type in _typeBuilderList)

            //{

            //    //依次对继承“IEntityTypeConfiguration<>”泛型接口的表及其字段约束规则定义类进行实现化操作。

            //    dynamic _configurationInstance = Activator.CreateInstance(type);

            //    builder.ApplyConfiguration(_configurationInstance);

            //}

            //EntityFrameworkCore> = 2.2或EntityFrameworkCore> = 2.2~EF Core = 7.0.1(至今)。

            //通过反射方式把“Data”项目中所有继承“IEntityTypeConfiguration<>”泛型接口的表及其字段约束规则定义类进行实现化操作,

            //优点:该方式简单,由于表及其字段约束规则在整个软件运行的生命周期中,只有1次,所以整个程序的开销不大。

            //缺点:没有过滤操作,性能上不如上述方式。黑盒化严重。

            builder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);

            base.OnModelCreating(builder);

        }

        #endregion

    }

}

3重构WebApi.Controllers.WeatherForecastController.Get方法

       [HttpGet(Name = "GetWeatherForecast")]

        public IEnumerable Get()

        {

            return _context.GetDbSet().ToList();

        }

4 EntityFrameworkCore与SqlSugar

    由于SqlSugar是国内开发者所开发的CURD开源中间件,比EntityFrameworkCore中间件的资源多的多,其内置功能实现也比EntityFrameworkCore中间件多,调用习惯也更加符合国内的开发者,学习曲线也低的多,但是到目前为止SqlSugar(V5.1.3.41)中间件还不支持抽离表及其字段的约束规则定义, 约束规则依然需要通过特性与实体属性成员结合才能实实现表及其字段的约束规则定义,这样实体与表的约束定义形成了紧密的耦合关系,因此在SqlSugar中间件解决这个问题前,本人通过权衡最终选择了EntityFrameworkCore中间件实现实体与表之间的CRUD操作。

    按F5执行程序,执行“GetWeatherForecast”Api,即可自动生成数据库及其表。

    对以上功能更为具体实现和注释见:221219_002ShopDemo(抽离表及其字段的约束规则定义)。

相关内容

热门资讯

银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...