You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现自定义EF HasConversion方法?Json序列化报错求解

问题分析与解决方案

你的自定义转换器存在三个核心问题:

  1. 扩展方法目标类型错误:你期望在PropertyBuilder(Property()方法的返回值)上链式调用,但当前方法是扩展EntityTypeBuilder<TEntity>,与调用方式不匹配。
  2. 泛型参数缺失:方法中使用了TClientSettings但未在泛型定义中声明,编译器无法识别该类型。
  3. JsonSerializer类型推断失败:未显式指定序列化/反序列化的目标类型,导致编译器无法解析lambda表达式的委托类型。

修正后的自定义转换器代码

方案一:精准匹配属性类型(推荐)

如果你的ClientSettings属性本身就是具体的设置类(比如CustomerClientSettings),可以直接扩展对应类型的PropertyBuilder:

public static class ClientSettingsConverter
{
    // 全局序列化配置,可根据需求调整
    private static readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions
    {
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
        IgnoreNullValues = true
    };

    public static PropertyBuilder<TClientSettings> MapClientSettings<TClientSettings>(this PropertyBuilder<TClientSettings> propertyBuilder)
        where TClientSettings : class, new()
    {
        propertyBuilder.HasConversion(
            serialize => JsonSerializer.Serialize(serialize, _jsonOptions),
            deserialize => JsonSerializer.Deserialize<TClientSettings>(deserialize, _jsonOptions)
        );

        return propertyBuilder;
    }
}

调用方式(完全符合你的预期):

modelBuilder.Entity<Customer>(entity =>
{
    entity.Property(k => k.Id).ValueGeneratedNever();
    entity.Property(e => e.ClientSettings).MapClientSettings<CustomerClientSettings>();
});

方案二:支持任意类型的属性

如果ClientSettings属性是object类型,需要同时指定属性类型和目标设置类:

public static class ClientSettingsConverter
{
    private static readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions
    {
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
        IgnoreNullValues = true
    };

    public static PropertyBuilder<TProperty> MapClientSettings<TProperty, TClientSettings>(this PropertyBuilder<TProperty> propertyBuilder)
        where TProperty : class
        where TClientSettings : class, new()
    {
        propertyBuilder.HasConversion(
            serialize => JsonSerializer.Serialize(serialize as TClientSettings, _jsonOptions),
            deserialize => JsonSerializer.Deserialize<TClientSettings>(deserialize, _jsonOptions) as TProperty
        );

        return propertyBuilder;
    }
}

调用方式:

entity.Property(e => e.ClientSettings).MapClientSettings<object, CustomerClientSettings>();

错误原因详解

你遇到的Cannot convert lambda expression to type 'Type' because it is not a delegate type报错,本质是因为:

  • 未声明TClientSettings泛型参数,编译器无法识别JsonSerializer.Deserialize<TClientSettings>中的类型参数
  • 扩展方法目标错误,导致链式调用时上下文不匹配,进一步干扰了编译器对lambda表达式的委托类型推断

内容的提问来源于stack exchange,提问作者Frodo_nicitel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 02:30:51