我希望这不是那么复杂。我确实有它的工作,但我想知道这是否是最好的:
我想使用 SQL Bulk Copy 类,更具体地说是采用 IDataReader 的重载。我的数据在几个 List<> 中,所以我需要一个“翻译器”。我找到了一个通过使用扩展方法来做到这一点的方法——我认为非常优雅!它在这里列出:http ://www.differentpla.net/content/2011/01/converting-ienumerablet-idatareader我认为这是一个很好的基础?!
那里显示的代码不完整,缺少一些从未调用过的不必要的重载。我将它们添加为 NotImplementedException。完整的版本可以在最后找到。
您可以通过在 IEnumerable<> 或 List<> 上调用 AsDataReader 方法来使用该类,并将数据中的列数以及用于遍历列的函数传递给它,如下所示:
List<NodeDB> myList = new List<NodeDB>();
myList.Add(myNode1);
myBulk.WriteToServer(myList.AsDataReader(3, NodeDB.GetValue));
NodeDB 类有一些字段和一个静态(!?)方法 GetValue,它获取当前迭代的位置(!?)和列,并返回适当的项目:
static object GetValue(NodeDB nodeDB, int i) {
object obj = null;
switch (i) {
case 0:
obj = nodeDB.ID;
break;
case 1:
obj = nodeDB.Latitude;
break;
case 2:
obj = nodeDB.Longitude;
break;
}
return obj;
}
在类中有一个带有自身实例的静态方法听起来很奇怪,我想知道是否有更好的方法。但更重要的是:我确实有几个类,比如 NodeDB,它们都有自己的特定 GetValues,组织成 List<>,每个类型都有一个 List<>。
我想将它们全部传递给一个通用的批量写入方法。
目前,我通过将不同的列表作为 IEnumberable 传递来做到这一点,然后在逐一比较它们之后将它们转换回原来的状态:
if (list is List<NodeDB>) {
} else if ( ....
在每种不同的情况下,我也需要处理正确的函数,即重复、重复和乏味 - 有没有办法从传递的 List 派生正确的 Func 参数?
如何更改我的类(从具有抽象 GetValues 的公共类派生)?我认为,所有 List<> 都可以作为 List 给出,并且所有对 GetValues 的调用都会达到它的目标。我试图这样做,但静态方法在基类中不能是抽象的。
或者我可以添加另一个参数,一个 TYPE 可能然后调用 Func 反对它?或者更改 IDataReader 扩展?
正如我所说,我迷路了......感谢您的帮助!拉尔夫
这里是带有所有接口实现的 IEnumerable 的完整 IDataReader 扩展:
using System;
using System.Collections.Generic;
using System.Data;
static class DataReaderExtensions {
public static IDataReader AsDataReader<TSource>(this IEnumerable<TSource> source, int fieldCount, Func<TSource, int, object> getValue) {
return new EnumerableDataReader<TSource>(source.GetEnumerator(), fieldCount, getValue);
//return EnumerableDataReader.Create(source, fieldCount, getValue);
}
}
//internal static class EnumerableDataReader {
// public static IDataReader Create<TSource>(IEnumerable<TSource> source, int fieldCount, Func<TSource, int, object> getValue) {
// return new EnumerableDataReader<TSource>(source.GetEnumerator(), fieldCount, getValue);
// }
//}
internal class EnumerableDataReader<TSource> : IDataReader {
private readonly IEnumerator<TSource> _source;
private readonly int _fieldCount;
private readonly Func<TSource, int, object> _getValue;
internal EnumerableDataReader(IEnumerator<TSource> source, int fieldCount, Func<TSource, int, object> getValue) {
_source = source;
_getValue = getValue;
_fieldCount = fieldCount;
}
public void Dispose() {
// Nothing.
}
public string GetName(int i) {
throw new NotImplementedException();
}
public string GetDataTypeName(int i) {
throw new NotImplementedException();
}
public Type GetFieldType(int i) {
throw new NotImplementedException();
}
public object GetValue(int i) {
return _getValue(_source.Current, i);
}
public int GetValues(object[] values) {
throw new NotImplementedException();
}
public int GetOrdinal(string name) {
throw new NotImplementedException();
}
public int FieldCount {
get { return _fieldCount; }
}
object IDataRecord.this[int i] {
get { throw new NotImplementedException(); }
}
object IDataRecord.this[string name] {
get { throw new NotImplementedException(); }
}
public void Close() {
throw new NotImplementedException();
}
public DataTable GetSchemaTable() {
throw new NotImplementedException();
}
public bool NextResult() {
throw new NotImplementedException();
}
public bool Read() {
return _source.MoveNext();
}
public int Depth { get; private set; }
public bool IsClosed { get; private set; }
public int RecordsAffected { get; private set; }
public bool IsDBNull(int i) {
throw new NotImplementedException();
}
public IDataReader GetData(int i) {
throw new NotImplementedException();
}
public DateTime GetDateTime(int i) {
throw new NotImplementedException();
}
public Decimal GetDecimal(int i) {
throw new NotImplementedException();
}
public String GetString(int i) {
throw new NotImplementedException();
}
public Double GetDouble(int i) {
throw new NotImplementedException();
}
public float GetFloat(int i) {
throw new NotImplementedException();
}
public Int64 GetInt64(int i) {
throw new NotImplementedException();
}
public Int32 GetInt32(int i) {
throw new NotImplementedException();
}
public Int16 GetInt16(int i) {
throw new NotImplementedException();
}
public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) {
throw new NotImplementedException();
}
public Guid GetGuid(int i) {
throw new NotImplementedException();
}
public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) {
throw new NotImplementedException();
}
public Char GetChar(int i) {
throw new NotImplementedException();
}
public Byte GetByte(int i) {
throw new NotImplementedException();
}
public Boolean GetBoolean(int i) {
throw new NotImplementedException();
}
}