SqlDataReader 在导出到 csv 时更改列名

SqlDataReader change column names when exporting to csv

我有一个通过 SqlDataReader 获取报告数据并将 SqlDataReader 发送到将内容导出到 .CSV 文件的方法的查询;但是,列名在 .CSV 文件中的显示方式与它们在数据库中的显示方式并不理想。

我不想更改查询本身(更改名称以包含空格),因为此查询是在另一个位置调用的,它映射到一个对象,而空格将不起作用。我不想创建重复的查询,因为维护可能会有问题。我也不想修改写出 .CSV 的方法,因为这是一种全局使用的方法。

我可以在填充数据 reader 之后但在将其发送到 .CSV 方法之前修改列名吗?如果是这样,如何?

如果我不能这样做,如果它是 DataTable 我可以这样做吗?

这里是一般流程:

    public static SqlDataReader RunMasterCSV(Search search)
    {
        SqlDataReader reader = null;

        using (Network network = new Network())
        {
            using (SqlCommand cmd = new SqlCommand("dbo.MasterReport"))
            {
                cmd.CommandType = CommandType.StoredProcedure;
                //Parameters here...

                network.FillSqlReader(cmd, ref reader); 

                <-- Ideally would like to find a solution here --> 
                return reader;
            }
        }
    }

    public FileInfo CSVFileWriter(SqlDataReader reader)
    {
        DeleteOldFolders();

        FileInfo file = null;

        if (reader != null)
        {
            using (reader)
            {
                var WriteDirectory = GetExcelOutputDirectory();
                double folderToSaveInto = Math.Ceiling((double)DateTime.Now.Hour / Folder_Age_Limit.TotalHours);
                string uploadFolder = GetExcelOutputDirectory() + "\" + DateTime.Now.ToString("ddMMyyyy") + "_" + folderToSaveInto.ToString();

                //Add directory for today if one does not exist
                if (!Directory.Exists(uploadFolder))
                    Directory.CreateDirectory(uploadFolder);

                //Generate random GUID fileName
                file = new FileInfo(uploadFolder + "\" + Guid.NewGuid().ToString() + ".csv");
                if (file.Exists)
                    file.Delete();

                using (file.Create()) { /*kill the file stream immediately*/};
                    StringBuilder sb = new StringBuilder();

                    if (reader.Read())
                    {
                        //write the column names
                        for (int i = 0; i < reader.FieldCount; i++)
                        {
                            AppendValue(sb, reader.GetName(i), (i == reader.FieldCount - 1));
                        }

                        //write the column names
                        for (int i = 0; i < reader.FieldCount; i++)
                        {
                            AppendValue(sb, reader[i] == DBNull.Value ? "" : reader[i].ToString(), (i == reader.FieldCount - 1));
                        }

                        int rowcounter = 1;

                        while (reader.Read())
                        {
                            for (int i = 0; i < reader.FieldCount; i++)
                            {
                                AppendValue(sb, reader[i] == DBNull.Value ? "" : reader[i].ToString(), (i == reader.FieldCount - 1));
                            }

                            rowcounter++;

                            if (rowcounter == MaxRowChunk)
                            {
                                using (var sw = file.AppendText())
                                {
                                    sw.Write(sb.ToString());
                                    sw.Close();
                                    sw.Dispose();
                                }

                                sb = new StringBuilder();
                                rowcounter = 0;
                            }
                        }

                        if (sb.Length > 0)
                        {
                            //write the last bit
                            using (var sw = file.AppendText())
                            {
                                sw.Write(sb.ToString());
                                sw.Close();
                                sw.Dispose();

                                sb = new StringBuilder();
                            }
                        }
                    }
                }
        }

        return file;
    }

我会尝试重构您的 CSVFileWriter。

首先你应该添加一个委托声明

public delegate string onColumnRename(string);

然后创建 CSVFileWriter 的重载,在其中将委托与 reader

一起传递
public FileInfo CSVFileWriter(SqlDataReader reader, onColumnRename renamer)
{
     // Move here all the code of the old CSVFileWriter
     .....
}

将之前CSVFileWriter的代码移到新方法中,从旧方法调用新方法

public FileInfo CSVFileWriter(SqlDataReader reader)
{
    // Pass null for the delegate to the new version of CSVFileWriter....
    return this.CSVFileWriter(reader, null)
}

这将使旧方法的现有客户满意。对他们来说什么都没有改变.....

在新版本的 CSVFileWriter 中,您更改了准备列名的代码

for (int i = 0; i < reader.FieldCount; i++)
{
    string colName = (renamer != null ? renamer(reader.GetName(i)) 
                                      : reader.GetName(i))
    AppendValue(sb, colName, (i == reader.FieldCount - 1));
}

现在只需要创建转换列名称的重命名函数

private string myColumnRenamer(string columnName)
{
    if(columnName == "yourNameWithoutSpaces")
        return "your Name with Spaces";
    else 
        return text;
}

这可以通过静态字典进行优化以删除 ifs 列表

此时您可以调用新的 CSVFileWriter 传递您的函数

FileInfo fi = CSVFileWrite(reader, myColumnRenamer);