导出到csv时,SqlDataReader更改列名

时间:2015-04-03 20:01:08

标签: c# sqldatareader

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

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

我可以在填写数据阅读器之后但在将其发送到.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;
    }

1 个答案:

答案 0 :(得分:1)

我会尝试重构你的CSVFileWriter。

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

public delegate string onColumnRename(string);

然后创建CSVFileWriter的重载,将代理与读者一起传递

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);