You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

186 lines
7.1 KiB
C#

// ============================================================================
// 【文件说明】HwPortalSearchDbContext.cs - 搜索子系统 EF Core 数据库上下文
// ============================================================================
// 这是 Entity Framework Core 的数据库上下文,专门用于搜索索引数据。
//
// 【什么是 DbContext
// DbContext 是 EF Core 的核心类,负责:
// 1. 管理数据库连接
// 2. 跟踪实体状态(新增、修改、删除)
// 3. 执行 LINQ 查询并转换为 SQL
// 4. 保存变更到数据库
//
// 【与 SqlSugar 的区别】
// 项目中同时使用了两个 ORM
// - SqlSugar用于业务表的 CRUD 操作(如 HwWeb, HwProductInfo
// - EF Core用于搜索索引表HwPortalSearchDoc
//
// 为什么搜索用 EF Core
// 1. EF Core 的 LINQ 查询更强大,支持复杂查询
// 2. EF Core 的迁移工具更成熟
// 3. 搜索索引是独立的读模型,用不同的 ORM 隔离
//
// 【与 Java Spring Boot 的对比】
// Java Spring Data JPA:
// @Entity
// @Table(name = "hw_portal_search_doc")
// public class HwPortalSearchDoc { ... }
//
// public interface SearchDocRepository extends JpaRepository<HwPortalSearchDoc, Long> {
// // JPA 自动实现 CRUD
// }
//
// EF Core:
// public class HwPortalSearchDbContext : DbContext {
// public DbSet<HwPortalSearchDoc> SearchDocs { get; }
// }
//
// 两者概念相似:
// - JPA 的 Repository ≈ EF Core 的 DbSet
// - JPA 的 EntityManager ≈ EF Core 的 DbContext
// ============================================================================
using Microsoft.EntityFrameworkCore;
namespace Admin.NET.Plugin.HwPortal;
/// <summary>
/// 搜索子系统专用 DbContext。
/// <para>
/// 【设计原则 - 单一职责】
/// 这个 DbContext 只管理搜索相关的实体,不包含业务实体。
///
/// 好处:
/// 1. 关注点分离:搜索逻辑和业务逻辑解耦
/// 2. 性能优化:可以单独配置搜索数据库连接
/// 3. 独立部署:搜索可以迁移到独立的数据库服务器
/// </para>
/// <para>
/// 【C# 语法知识点 - 继承 DbContext】
/// public class HwPortalSearchDbContext : DbContext
///
/// DbContext 是 EF Core 的基类,继承后:
/// 1. 可以定义 DbSet&lt;T&gt; 属性来映射表
/// 2. 可以重写 OnModelCreating 配置映射
/// 3. 可以重写 OnConfiguring 配置连接
///
/// 对比 Java JPA
/// Java 不需要显式继承 DbContext而是用 @Entity 和 Repository。
/// </para>
/// </summary>
public class HwPortalSearchDbContext : DbContext
{
/// <summary>
/// 构造函数(依赖注入)。
/// <para>
/// 【C# 语法知识点 - 构造函数注入】
/// public HwPortalSearchDbContext(DbContextOptions&lt;HwPortalSearchDbContext&gt; options) : base(options)
///
/// DbContextOptions&lt;T&gt; 包含数据库连接配置:
/// - 连接字符串
/// - 数据库提供者MySQL, PostgreSQL, SQLite 等)
/// - 其他配置选项
///
/// : base(options) 把配置传给父类 DbContext。
///
/// 对比 Java Spring Boot
/// Java 通常用 @Autowired 注入 DataSource 或 EntityManagerFactory
/// @Autowired
/// public SearchRepository(EntityManager em) {
/// this.em = em;
/// }
///
/// C# 的构造函数注入是 DI 的标准方式。
/// </para>
/// </summary>
/// <param name="options">数据库上下文配置选项</param>
public HwPortalSearchDbContext(DbContextOptions<HwPortalSearchDbContext> options) : base(options)
{
}
/// <summary>
/// 搜索文档表映射。
/// <para>
/// 【C# 语法知识点 - DbSet&lt;T&gt; 属性】
/// public DbSet&lt;HwPortalSearchDoc&gt; SearchDocs => Set&lt;HwPortalSearchDoc&gt;();
///
/// DbSet&lt;T&gt; 是 EF Core 的"表映射"
/// - 每个 DbSet&lt;T&gt; 对应数据库中的一张表
/// - 可以用 LINQ 查询_db.SearchDocs.Where(x => x.Title.Contains("关键词"))
/// - 可以增删改_db.SearchDocs.Add(doc), _db.SearchDocs.Remove(doc)
///
/// => Set&lt;HwPortalSearchDoc&gt;() 是表达式体属性:
/// - 等价于 { return Set&lt;HwPortalSearchDoc&gt;(); }
/// - Set&lt;T&gt;() 是 DbContext 的方法,返回 DbSet&lt;T&gt;
///
/// 对比 Java JPA
/// Java 的 Repository 接口类似:
/// public interface SearchDocRepository extends JpaRepository<HwPortalSearchDoc, Long> {
/// // JPA 自动实现 CRUD
/// }
///
/// C# 的 DbSet 更接近底层,但 LINQ 查询更强大。
/// </para>
/// </summary>
public DbSet<HwPortalSearchDoc> SearchDocs => Set<HwPortalSearchDoc>();
/// <summary>
/// 配置实体映射。
/// <para>
/// 【C# 语法知识点 - OnModelCreating 方法】
/// protected override void OnModelCreating(ModelBuilder modelBuilder)
///
/// OnModelCreating 是 DbContext 的虚方法,用于:
/// 1. 配置实体到表的映射
/// 2. 配置列类型、索引、约束
/// 3. 配置关系(一对多、多对多)
///
/// ModelBuilder 是"流畅 API"Fluent API
/// - 用链式方法调用配置映射
/// - 比 Data Annotations特性更灵活
///
/// 对比 Java JPA
/// Java 可以用 @Column, @Table 等注解配置:
/// @Column(name = "content", columnDefinition = "LONGTEXT")
/// private String content;
///
/// 或者用 JPA 的 @Entity + @Table 注解。
///
/// EF Core 的 Fluent API 更强大,适合复杂配置。
/// </para>
/// </summary>
/// <param name="modelBuilder">模型构建器</param>
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// 调用父类方法(如果有基础配置)。
base.OnModelCreating(modelBuilder);
// 【配置 HwPortalSearchDoc 实体】
// modelBuilder.Entity&lt;HwPortalSearchDoc&gt;(entity => { ... })
// 对特定实体进行详细配置。
modelBuilder.Entity<HwPortalSearchDoc>(entity =>
{
// 【列类型配置】
// entity.Property(x => x.Content).HasColumnType("longtext")
//
// 为什么显式指定列类型?
// 1. 不同数据库提供者的默认映射不同
// - MySQL: string → VARCHAR(255)
// - PostgreSQL: string → TEXT
// 2. 搜索内容可能很长,需要 longtextMySQL 的 4GB 文本类型)
// 3. 显式声明避免迁移时类型变化
//
// 对比 Java JPA
// Java: @Column(name = "content", columnDefinition = "LONGTEXT")
entity.Property(x => x.Content).HasColumnType("longtext");
// 【JSON 列类型】
// MySQL 5.7+ 支持 JSON 类型:
// - 自动验证 JSON 格式
// - 支持 JSON 函数查询(如 JSON_EXTRACT
// - 更高效的存储
entity.Property(x => x.RouteQueryJson).HasColumnType("json");
});
}
}