我的目标是从数据源检索数据,向其中添加一些元数据并将其插入另一个目标。如何向DataReader添加列
该目标具有四个多列然后是源(计算列)的架构。
我正在使用SqlBulkCopy,它需要一个阅读器与所有列(包括4计算)。
有没有办法给DataReader手动添加列?或者如果它不可能有什么替代方案我的数据插入?
我的目标是从数据源检索数据,向其中添加一些元数据并将其插入另一个目标。如何向DataReader添加列
该目标具有四个多列然后是源(计算列)的架构。
我正在使用SqlBulkCopy,它需要一个阅读器与所有列(包括4计算)。
有没有办法给DataReader手动添加列?或者如果它不可能有什么替代方案我的数据插入?
有可能
只是为了得到一个想法,这可能是一个简单的实现(我跳过了大多数方法)
public class WrapperDataReader : IDataReader
{
private IDataReader reader;
public WrapperDataReader(IDataReader reader)
{
this.reader = reader;
}
public void Close()
{
reader.Close();
}
public int Depth
{
get { return reader.Depth; }
}
public DataTable GetSchemaTable()
{
var schemaTable = reader.GetSchemaTable();
// add your computed column to the schema table
schemaTable.Rows.Add(...);
return schemaTable;
}
public bool GetBoolean(int i)
{
return reader.GetBoolean(i);
}
public int GetOrdinal(string name)
{
if (name.Equals("displayName", StringComparison.InvariantCultureIgnoreCase))
return 15;
return reader.GetOrdinal(name);
}
public string GetString(int i)
{
if (i == 15)
return String.Format("{0}, {1}", GetString(1), GetString(2)); // lastname, firstname
return reader.GetString(i);
}
}
更新
既然你propably使用在WriteToServer方法,你可以使用接受一个DataTable重载代替。
var connectionString = "...";
var copy = new SqlBulkCopy(connectionString, SqlBulkCopyOptions.Default);
copy.DestinationTableName = "Customers";
var reader = new SqlDataReader();
var table = new DataTable();
table.Load(reader);
table.Columns.Add("DisplayName", typeof(string), "lastname, firstname");
table.Columns.Add("CustomerCode", typeof(string));
foreach (DataRow row in table.Rows)
row["CustomerCode"] = ((int)row["id"] + 10000).ToString();
copy.WriteToServer(table);
一个DataReader是一个只读结构,所以它不能被修改。 您可以改用DataTable。
数据读取器仅用于读取数据。您无法修改其模式或数据值。数据集/数据表就是为此目的而设计的。
,我发现了另一个可能的解决方案,我目前使用:
从现有DataReader
创建下列对象:
IEnumerable<object[]>
- 它代表了数据
List<Column>
- 它代表数据列DataReader
。
修改数据,并添加额外的列
创建方法AsDataReader(IEnumerable<object[]> updatedData,updatedColumns List<Column>)
它获取更新的对象和收益*修改DataReader
我有一些困难,实现GetBytes方法.. –
你真的需要实现GetBytes会()方法自己吗?为什么不将该方法传递给基础DataReader? 'return reader.GetBytes(i,fieldOffset,buffer,bufferoffset,length);' –
@Yosi其实你不需要实现'GetBytes',也不需要像'GetSchemaTable'这样复杂的东西,如果你所要做的只是使用这个类作为'SqlBulkCopy'的包装器,它使用的'IDataReader'的唯一方法是'bool IsDbNull(int)','bool Read()','int GetOrdnal(string)','GetValue(int)',和'int FieldCount'属性。其他的都可以抛出一个'NotImplmentedException()',我不得不这样做我自己,这就是所需要的。 –