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#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// ============================================================================
// 【文件说明】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");
});
}
}