Some checks are pending
Publish Platform NuGet Packages / build (push) Waiting to run
修复在 EF Core 10 中使用 JSON 值对象时出现的映射错误:
## 问题
在 EF Core 10 中,GwRouteMatch 类的嵌套集合属性(Headers 和 QueryParameters)
导致 "Unable to determine the relationship" 错误。
## 解决方案
1. 在 PlatformDbContext 中使用 modelBuilder.Ignore<> 忽略相关类型
2. 将 OwnsOne().ToJson() 配置改为使用值转换器(Value Converter)
将对象序列化为 JSON 字符串存储到 jsonb 列
3. 在 GwRouteMatch 类的 Headers 和 QueryParameters 属性上添加 [NotMapped] 特性
4. 添加 [JsonInclude] 特性确保序列化包含这些属性
## 技术细节
- 使用 HasColumnType("jsonb") 存储 JSON 数据
- 使用值转换器处理对象序列化/反序列化
- 保持与 PostgreSQL jsonb 类型的兼容性
## 文件变更
- 修改: Fengling.Platform.Domain/AggregatesModel/GatewayAggregate/GwRouteMatch.cs
- 修改: Fengling.Platform.Infrastructure/PlatformDbContext.cs
关联任务: IMPL-4 (EF Core 兼容性修复)
关联重构计划: WFS-gateway-refactor
116 lines
2.6 KiB
C#
116 lines
2.6 KiB
C#
using Microsoft.EntityFrameworkCore;
|
||
using System.ComponentModel.DataAnnotations.Schema;
|
||
using System.Text.Json.Serialization;
|
||
|
||
namespace Fengling.Platform.Domain.AggregatesModel.GatewayAggregate;
|
||
|
||
/// <summary>
|
||
/// 路由匹配配置(值对象)
|
||
/// 对应 YARP 的 RouteMatch,以 JSON 存储在数据库中
|
||
/// </summary>
|
||
public class GwRouteMatch
|
||
{
|
||
/// <summary>
|
||
/// 路径匹配模式
|
||
/// </summary>
|
||
public string Path { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// HTTP 方法列表(如 ["GET", "POST"])
|
||
/// </summary>
|
||
public List<string>? Methods { get; set; }
|
||
|
||
/// <summary>
|
||
/// Host 匹配列表(如 ["api.example.com", "*.example.com"])
|
||
/// </summary>
|
||
public List<string>? Hosts { get; set; }
|
||
|
||
/// <summary>
|
||
/// Header 匹配规则
|
||
/// </summary>
|
||
[NotMapped]
|
||
[JsonInclude]
|
||
public List<GwRouteHeader>? Headers { get; set; }
|
||
|
||
/// <summary>
|
||
/// 查询参数匹配规则
|
||
/// </summary>
|
||
[NotMapped]
|
||
[JsonInclude]
|
||
public List<GwRouteQueryParameter>? QueryParameters { get; set; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// Header 匹配规则(值对象)
|
||
/// </summary>
|
||
public class GwRouteHeader
|
||
{
|
||
/// <summary>
|
||
/// Header 名称
|
||
/// </summary>
|
||
public string Name { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 匹配值列表
|
||
/// </summary>
|
||
public List<string> Values { get; set; } = [];
|
||
|
||
/// <summary>
|
||
/// 匹配模式
|
||
/// </summary>
|
||
public GwHeaderMatchMode Mode { get; set; } = GwHeaderMatchMode.ExactHeader;
|
||
|
||
/// <summary>
|
||
/// 是否区分大小写
|
||
/// </summary>
|
||
public bool IsCaseSensitive { get; set; } = false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询参数匹配规则(值对象)
|
||
/// </summary>
|
||
public class GwRouteQueryParameter
|
||
{
|
||
/// <summary>
|
||
/// 参数名称
|
||
/// </summary>
|
||
public string Name { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 匹配值列表
|
||
/// </summary>
|
||
public List<string> Values { get; set; } = [];
|
||
|
||
/// <summary>
|
||
/// 匹配模式
|
||
/// </summary>
|
||
public GwQueryParameterMatchMode Mode { get; set; } = GwQueryParameterMatchMode.Exact;
|
||
|
||
/// <summary>
|
||
/// 是否区分大小写
|
||
/// </summary>
|
||
public bool IsCaseSensitive { get; set; } = false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Header 匹配模式
|
||
/// </summary>
|
||
public enum GwHeaderMatchMode
|
||
{
|
||
ExactHeader = 0,
|
||
Prefix = 1,
|
||
Contains = 2,
|
||
NotContains = 3,
|
||
Exists = 4
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查询参数匹配模式
|
||
/// </summary>
|
||
public enum GwQueryParameterMatchMode
|
||
{
|
||
Exact = 0,
|
||
Contains = 1,
|
||
Prefix = 2,
|
||
Exists = 3
|
||
} |