簡體   English   中英

有什么辦法可以使這兩個塊的通用功能

[英]Is there any way to make common function out of these two blocks

我有兩個街區; 在每個塊中,我使用命令和閱讀器從表中檢索數據並轉換數據,然后更新相同的數據。 我希望通過將表名、類型和轉換函數從這兩個塊傳遞給該函數來提取通用函數

下面是相同的代碼,

// 塊 #1

using var queryProjectSteamSystemsCommand = dbContext.Database.GetDbConnection().CreateCommand();
queryProjectSteamSystemsCommand.CommandText = @"SELECT ""Id""::varchar, ""InitialObject""::varchar from ""DesignHubProjectSteamSystems""";
using var steamSystemProjectsReader = queryProjectSteamSystemsCommand.ExecuteReader();

if (steamSystemProjectsReader.HasRows)
{
    while (steamSystemProjectsReader.Read())
    {
        var id = steamSystemProjectsReader.IsDBNull(0) ? Guid.Empty : Guid.Parse(steamSystemProjectsReader.GetString(0));
        var steamSystemJson = steamSystemProjectsReader.IsDBNull(1) ? "null" : steamSystemProjectsReader.GetString(1);
        var projSteamSystemInitialObj = JsonConvert.DeserializeObject<OldSteamSystem>(steamSystemJson);
        string json = JsonConvert.SerializeObject(TransformProjectSteamSystem(projSteamSystemInitialObj)).Replace("'", "''", StringComparison.Ordinal);
        migrationBuilder.Sql($"UPDATE \"DesignHubProjectSteamSystems\"  SET \"InitialObject\" = '{json}'::jsonb WHERE \"Id\" = '{id}'");
    }
}
steamSystemProjectsReader.Close();

// 塊 #2

using var queryProjectFuelSystemsCommand = dbContext.Database.GetDbConnection().CreateCommand();
queryProjectFuelSystemsCommand.CommandText = @"SELECT ""Id""::varchar, ""InitialObject""::varchar from ""DesignHubProjectFuelSystems""";
using var fuelSystemProjectsReader = queryProjectFuelSystemsCommand.ExecuteReader();

if (fuelSystemProjectsReader.HasRows)
{
    while (fuelSystemProjectsReader.Read())
    {
        var id = fuelSystemProjectsReader.IsDBNull(0) ? Guid.Empty : Guid.Parse(fuelSystemProjectsReader.GetString(0));
        var fuelSystemJson = fuelSystemProjectsReader.IsDBNull(1) ? "null" : fuelSystemProjectsReader.GetString(1);
        var projFuelSystemInitialObj = JsonConvert.DeserializeObject<OldFuelSystem>(fuelSystemJson);

        string json = JsonConvert.SerializeObject(TransformProjectFuelSystem(projFuelSystemInitialObj)).Replace("'", "''", StringComparison.Ordinal);
        migrationBuilder.Sql($"UPDATE \"DesignHubProjectFuelSystems\"  SET \"InitialObject\" = '{json}'::jsonb WHERE \"Id\" = '{id}'");
    }
}
fuelSystemProjectsReader.Close();

我不能將OldSteamSystemOldFuelSystem兩個不同的類結合起來。 我無法從這兩者中制作任何熟悉的接口和抽象類。

那么,任何人都可以讓我知道如何使用它來制作一個通用功能嗎?

提前謝謝了!!!

使用泛型,並詢問表名和轉換對象的方法。

void DoTheThing<TSystem>(string tableName, Func<TSystem, TSystem> transform)
{
    using var command = dbContext.Database.GetDbConnection().CreateCommand();
    command.CommandText = @$"SELECT ""Id""::varchar, ""InitialObject""::varchar from ""{tableName}""";
    // I know I complain about SQL injection, you get to fix this one...

    using var reader = command.ExecuteReader();

    if (reader.HasRows)
    {
        while (reader.Read())
        {
            var id = reader.IsDBNull(0) ? Guid.Empty : Guid.Parse(reader.GetString(0));
            var initialJson = reader.IsDBNull(1) ? "null" : reader.GetString(1);
            var initialObj = JsonConvert.DeserializeObject<TSystem>(initialJson);
            
            // this uses the "transform" parameter, IE a method your caller provides
            string transformedJson = JsonConvert.SerializeObject(transform(initialObj)).Replace("'", "''", StringComparison.Ordinal);
            migrationBuilder.Sql($"UPDATE \"{tableName}\"  SET \"InitialObject\" = '{transformedJson}'::jsonb WHERE \"Id\" = '{id}'");
            // again, SQL injection
        }
    }

    reader.Close();
}

如果transform方法采用一種類型並返回一種類型,則將方法簽名更改為

void DoTheThing<TSystem, TTransformed>(string tableName, Func<TSystem, TTransformed> transform)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM