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);
我有一个通过 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);