.net 6.0 框架集成ef实战,步骤详解

发布于:2024-05-15 ⋅ 阅读:(148) ⋅ 点赞:(0)

一、代码框架搭建

搭建如下代码架构:

重点含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);


网站公告

今日签到

点亮在社区的每一天
去签到