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

C#如何抽取两段相似数据库读写转换逻辑为通用公共函数

实现方案

核心通过泛型+委托的组合实现代码复用,不需要为OldSteamSystem、OldFuelSystem提取公共接口或合并类定义,完全兼容两类差异较大的旧实体结构。

可变逻辑全部通过参数传入:

  • 表名通过字符串参数传入,用于动态拼接查询、更新SQL
  • 旧实体类型通过泛型参数指定,适配不同类型的反序列化需求
  • 转换逻辑通过Func委托传入,公共方法不需要感知具体的实体转换规则
    其余固定的数据库操作、DataReader读取、JSON序列化/反序列化、更新执行逻辑全部下沉到公共函数统一维护。

通用公共函数代码

private void ProcessTableInitialObjectMigration<TOldEntity>(
    DbContext dbContext,
    MigrationBuilder migrationBuilder,
    string tableName,
    Func<TOldEntity, object> convertDelegate)
{
    using var queryCmd = dbContext.Database.GetDbConnection().CreateCommand();
    queryCmd.CommandText = @$"SELECT ""Id""::varchar, ""InitialObject""::varchar FROM ""{tableName}""";
    
    // 补全连接打开逻辑,避免连接未开启时执行报错
    if (queryCmd.Connection.State != ConnectionState.Open)
    {
        queryCmd.Connection.Open();
    }

    using var reader = queryCmd.ExecuteReader();
    if (!reader.HasRows)
    {
        reader.Close();
        return;
    }

    while (reader.Read())
    {
        var recordId = reader.IsDBNull(0) ? Guid.Empty : Guid.Parse(reader.GetString(0));
        var initialJson = reader.IsDBNull(1) ? "null" : reader.GetString(1);
        
        // 按传入的泛型类型反序列化旧实体
        var oldEntityInstance = JsonConvert.DeserializeObject<TOldEntity>(initialJson);
        // 调用传入的转换委托完成结构映射
        var convertedEntity = convertDelegate(oldEntityInstance);
        // 序列化后做单引号转义,兼容SQL语法
        var updatedJsonStr = JsonConvert.SerializeObject(convertedEntity)
            .Replace("'", "''", StringComparison.Ordinal);
        
        migrationBuilder.Sql(@$"UPDATE ""{tableName}"" SET ""InitialObject"" = '{updatedJsonStr}'::jsonb WHERE ""Id"" = '{recordId}'");
    }

    reader.Close();
}

调用方式

原有两段重复的业务逻辑,替换为以下两行调用即可:

// 处理蒸汽系统表
ProcessTableInitialObjectMigration<OldSteamSystem>(
    dbContext,
    migrationBuilder,
    "DesignHubProjectSteamSystems",
    TransformProjectSteamSystem);

// 处理燃油系统表
ProcessTableInitialObjectMigration<OldFuelSystem>(
    dbContext,
    migrationBuilder,
    "DesignHubProjectFuelSystems",
    TransformProjectFuelSystem);

补充优化建议

原SQL拼接写法存在隐式注入风险,可将更新逻辑改为参数化执行,无需手动转义单引号,稳定性更强,调整公共函数内的更新段代码即可,上层调用无需修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 00:51:23