一、代码框架搭建
搭建如下代码架构:
重点含EntityFrameworkCore工程,该工程中包含AppDbContext.cs和数据表实体AggregateObject
1、AppDbContext 代码案例
//AppDbContext 代码案例
using Microsoft.EntityFrameworkCore;
namespace EntityFrameworkCore
{
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// 增加以下代码配置
modelBuilder.ConfigDatabaseDescription();
}
public DbSet<CFUserAggregate> CFUserAggregate { get; set; } // 示例:User 是你的实体类
// 添加其他 DbSet<T> 来表示其他数据表
}
}
2、实体案例
1)AggregateRootBase类:
存放表公共字段,例状态、创建时间等
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
namespace EntityFrameworkCore
{
public abstract class AggregateRootBase
{
[Key] // 主键
[StringLength(36)] // 字符串长度限制
[DbDescription("主键ID")]
public Guid? Id { get; set; }
[StringLength(36)]
[DbDescription("创建人ID")]
public Guid? CreateUserGuid { get; set; }
[Required]
[DbDescription("创建时间")]
public DateTime? CreateDateTime { get; set; }
[StringLength(36)]
[DbDescription("修改人ID")]
public Guid? ModifyUserGuid { get; set; }
[DbDescription("修改时间")]
public DateTime? ModifyDateTime { get; set; }
}
}
2)CFUserAggregate 实体
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
namespace EntityFrameworkCore
{
[Table("CF_User")]
[DbDescription("用户表")]
public class CFUserAggregate : AggregateRootBase
{
[Required]
[StringLength(15)] // 字符串长度限制
[DbDescription("登录人手机号码")]
public string PhoneNumber { get; set; }
[Required]
[StringLength(100)] // 字符串长度限制
[DbDescription("登录密码")]
public string Password { get; set; }
[Required]
[StringLength(10)]
[DbDescription("状态: New:新增;Active:有效;InActive:无效/注销")]
public string? RecordStatus { get; set; }
}
}
二、引入EF依赖
具体步骤:
三、配置数据库连接
appsettings.json文件中配置数据库访问链接
四、注册 AppDbContext 作为服务
具体代码:
#region 注册 AppDbContext 作为服务
// 添加数据库上下文服务
//builder.Services.AddDbContext<AppDbContext>(options =>
//{
// var connectionString = builder.Configuration.GetConnectionString("MySqlConnection");
// options.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString));
//});
builder.Services.AddDbContext<AppDbContext>(
optionsAction: x =>
{
x.UseMySql( builder.Configuration.GetConnectionString("MySqlConnection"), new MySqlServerVersion(new Version(8, 0, 23)));
});
//这段代码是使用.NET Core(或.NET框架)中的依赖注入(Dependency Injection)功能。
//在这里,AddScoped 是指将服务注册为“作用域”生命周期,
//表示每次 HTTP 请求时都会创建一个新的实例,但在同一个请求内的所有地方都会共享同一个实例。
builder.Services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
//builder.Services.AddScoped<RegisterServices>(); // 注册 YourService 类 参考案例
#endregion
五、将实体表更新到数据库中
在程序包管理器控制台执行下面的命令
//执行下面的命令生产待执行到数据库中的类文件
Add-Migration CF_User20240508
//更新到数据库中
Update-Database
命令执行成功之后会产生相关类文件
命令执行成功之后会在数据库中产生对应表
六、在控制器中通过表实体访问数据库
七、拓展1:实体字段描述更新到数据库字段说明
1、将实体字段描述更新到数据库字段说明中,如下效果
SELECT COLUMN_NAME, COLUMN_COMMENT
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = '数据库名称' AND TABLE_NAME = '表名';
2、具体实现步骤
1)DbDescriptionAttribute 类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EntityFrameworkCore
{
//
// 摘要:
// 实体在数据库中的表和列的说明 在迁移的Up方法中调用(确保在所有表创建和修改完成后,避免找不到表和列)
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field, Inherited = true, AllowMultiple = false)]
public class DbDescriptionAttribute : Attribute
{
//
// 摘要:
// 说明
public virtual string Description
{
get;
}
//
// 摘要:
// 初始化新的实例
//
// 参数:
// description:
// 说明内容
public DbDescriptionAttribute(string description)
{
Description = description;
}
}
}
2)MigrationBuilderExtensions类:
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Microsoft.EntityFrameworkCore.Utilities;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using Microsoft.EntityFrameworkCore;
namespace EntityFrameworkCore
{
/// <summary>
/// 表实体中表名、字段加字段说明
/// </summary>
public static class MigrationBuilderExtensions
{
public static void AddOrUpdateTableDescription(this MigrationBuilder migrationBuilder, string tableName, string description, string schema = "dbo")
{
if (!string.IsNullOrEmpty(description) && description.Contains('\''))
{
description = description.Replace("'", "''");
}
migrationBuilder.Sql("ALTER TABLE {tableName} COMMENT '{tableDescription}';".Replace("{tableDescription}", description).Replace("{schema}", schema).Replace("{tableName}", tableName));
}
public static void AddOrUpdateColumnDescription(this MigrationBuilder migrationBuilder, string tableName, string columnName, string columnType, bool isNullable, string description, string schema = "dbo")
{
Console.WriteLine(description);
if (!string.IsNullOrEmpty(description) && description.Contains('\''))
{
description = description.Replace("'", "''");
}
migrationBuilder.Sql("ALTER TABLE {tableName} MODIFY COLUMN {columnName} {columnType} {isNullable} COMMENT '{columnDescription}';".Replace("{columnDescription}", description).Replace("{schema}", schema).Replace("{tableName}", tableName)
.Replace("{columnName}", columnName)
.Replace("{columnType}", columnType)
.Replace("{isNullable}", isNullable == true ? "" : " NOT NULL ")
);
}
public static MigrationBuilder ApplyDatabaseDescription(this MigrationBuilder migrationBuilder, Microsoft.EntityFrameworkCore.Migrations.Migration migration)
{
string text = "dbo";
string name = "DbDescription";
foreach (var entityType in migration.TargetModel.GetEntityTypes())
{
string tableName = entityType.GetTableName();
string schema = entityType.GetSchema();
Console.WriteLine("tableName:" + tableName);
Console.WriteLine("schema:" + schema);
IAnnotation annotation = entityType.FindAnnotation(name);
if (annotation != null)
{
Console.WriteLine("annotation.Value:" + annotation.Value.ToString());
migrationBuilder.AddOrUpdateTableDescription(tableName, annotation.Value.ToString(), string.IsNullOrEmpty(schema) ? text : schema);
}
foreach (var property in entityType.GetProperties())
{
IAnnotation annotation2 = property.FindAnnotation(name);
if (annotation2 != null)
{
migrationBuilder.AddOrUpdateColumnDescription(tableName, property.GetColumnName(), property.GetColumnType(), property.IsNullable, annotation2.Value.ToString(), string.IsNullOrEmpty(schema) ? text : schema);
}
}
}
return migrationBuilder;
}
}
}
3)ModelBuilderExtensions类:
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Reflection;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
namespace EntityFrameworkCore
{
public static class ModelBuilderExtensions
{
// 自定义方法,用于将描述信息应用到数据库中
public static ModelBuilder ConfigDatabaseDescription(this ModelBuilder modelBuilder)
{
foreach (IMutableEntityType entityType in modelBuilder.Model.GetEntityTypes())
{
if (entityType.FindAnnotation("DbDescription") == null && (entityType.ClrType?.CustomAttributes.Any((CustomAttributeData attr) => attr.AttributeType == typeof(DbDescriptionAttribute)) ?? false))
{
entityType.AddAnnotation("DbDescription", (entityType.ClrType.GetCustomAttribute(typeof(DbDescriptionAttribute)) as DbDescriptionAttribute)?.Description);
}
foreach (IMutableProperty property in entityType.GetProperties())
{
if (property.FindAnnotation("DbDescription") != null || !(property.PropertyInfo?.CustomAttributes.Any((CustomAttributeData attr) => attr.AttributeType == typeof(DbDescriptionAttribute)) ?? false))
{
continue;
}
PropertyInfo propertyInfo = property.PropertyInfo;
Type type = propertyInfo?.PropertyType;
property.AddAnnotation("DbDescription", (propertyInfo.GetCustomAttribute(typeof(DbDescriptionAttribute)) as DbDescriptionAttribute)?.Description);
}
}
return modelBuilder;
}
}
}
4)在第5步执行完毕之后,在生成的文件中添加如下代码:
migrationBuilder.ApplyDatabaseDescription(this);