【发布时间】:2020-01-09 22:09:55
【问题描述】:
我用一个方法创建了一个小型 ETL 程序,它只接受源数据库的连接字符串和目标数据库的连接字符串。
基本上有5个步骤:
第 1 步。从源中选择数据。
步骤 2. 在目标上创建一个临时表。
步骤 3. 将数据从源加载到目标上的临时。
步骤 4. 将临时表中的数据合并到实际目标表中。
步骤 5. 删除临时表
这对于需要进行的单个转换非常有效,但我有大约 20 个不同的 ETL“工作”需要进行。
因此,与其逐字复制和粘贴相同的方法 19 次不同,我想定义一个基类来定义这个单一方法一次,然后从每个子类调用这个单一方法,用它自己的选择,创建, 合并和删除语句。
这可能吗?
基类:
public class ETLBase
{
private static string Select;
private static string CreateTemp;
private static string Merge;
private static string CleanUp;
private static string DestinationTable;
public static void ExecuteJob(string sourceConnectionString, string destinationConnectionString)
{
using (OracleConnection sourceConnection = new OracleConnection(sourceConnectionString))
{
sourceConnection.Open();
OracleCommand selectCommand = new OracleCommand(Select, sourceConnection);
OracleDataReader reader = selectCommand.ExecuteReader();
using (SqlConnection destinationConnection = new SqlConnection(destinationConnectionString))
{
destinationConnection.Open();
SqlCommand createTempCommand = new SqlCommand(CreateTemp, destinationConnection);
createTempCommand.ExecuteNonQuery();
SqlCommand mergeCommand = new SqlCommand(Merge, destinationConnection);
SqlCommand dropCommand = new SqlCommand(CleanUp, destinationConnection);
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection))
{
bulkCopy.DestinationTableName = DestinationTable;
try
{
bulkCopy.WriteToServer(reader);
mergeCommand.ExecuteNonQuery();
dropCommand.ExecuteNonQuery();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
reader.Close();
}
}
}
}
}
}
儿童班:
public class ChildETL: ETLBase
{
private static string Select = @"Select THIS DataStatement";
private static string CreateTemp = @"CREATE TABLE Statement";
private static string Merge = @"Merge Table statement";
private static string CleanUp = "DROP TABLE Statement";
private static string DestinationTable = "##TempTable";
}
然后像这样执行它,但是每个子类使用自己定义的字段,所以它使用自己的 SQL 语句。
public class Program
{
public static void Main(string[] args)
{
IConfiguration config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", true, true)
.Build();
string schoolDBConnection = config["SchoolConnection"];
string courseDBConnection = config["CourseConnection"];
string teacherDBConnection = config["Connection"];
ChildETLA.ExecuteJob(schoolDBConnection, courseDBConnection);
ChildETLB.ExecuteJob(teacherDBConnection, courseDBConnection);
//...and so on for each child ETL class
}
}
【问题讨论】:
-
类继承仅适用于实例属性/方法。也许您可以更新基类的方法以接收 Select、CreateTemp 等作为参数,将该方法标记为受保护,并在您调用包含参数的基类方法的每个子类上创建一个新的 ExecuteJob 方法。我希望这会有所帮助。
-
在这种情况下没有真正需要使用继承。只需将命令字符串添加为方法参数,然后从每个作业中调用 ExecuteJob() 方法。
标签: c# sql oop inheritance .net-core