如何使用 SqlBulkCopy 编写 IAsyncEnumerable
How to use SqlBulkCopy to write an IAsyncEnumerable
我有以下方法 returns 和 IAsyncEnumerable<T>
:
async IAsyncEnumerable<T> RunReport()
{
var handler = new HttpClientHandler();
var client = new HttpClient(handler);
client.BaseAddress = new Uri("");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var settings = new JsonSerializerSettings();
var jsonFormatter = new JsonMediaTypeFormatter() { SerializerSettings = settings };
var requestMessage = new HttpRequestMessage(HttpMethod.Get, "api/controler");
var response = await client.SendAsync(requestMessage);
response.EnsureSuccessStatusCode();
using (var stream = await response.Content.ReadAsStreamAsync())
{
using (var reader = new StreamReader(stream))
{
while (!reader.EndOfStream)
{
var linesJson = await reader.ReadLineAsync();
var line = JsonConvert.DeserializeObject<List<T>>(linesJson, jsonFormatter.SerializerSettings);
foreach (var line in lines)
yield return line;
}
}
}
}
我想使用 SqlBulkCopy
的 WriteToServerAsync
方法将该结果流式传输到数据库,但不知道如何将其转换为 IDataReader
或任何WriteToServerAsync
的重载列表中的其他类型。
我愿意使用批量复制以外的其他方式,前提是它具有合理的性能。
使用示例 here,我想出了一个 IDataReader,它采用 IAsyncEnumerable,并实现了接口的适当部分。
public class GenericDataReader<T> : IDataReader where T : class
{
private readonly IAsyncEnumerator<T> _asychEnumerator;
private readonly List<FieldInfo> _fields = new List<FieldInfo>();
public GenericDataReader(IAsyncEnumerable<T> asyncEnumerable)
{
_asychEnumerator = asyncEnumerable.GetAsyncEnumerator();
foreach (FieldInfo fieldinfo in typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public))
{
_fields.Add(fieldinfo);
}
}
public int FieldCount => _fields.Count;
public void Dispose() { Close(); }
public bool Read()
{
return _asycEnumerator.MoveNextAsync().Result;
}
public async void Close(){ await _asychEnumerator.DisposeAsync(); }
public Type GetFieldType(int i){ return _fields[i].FieldType; }
public string GetName(int i) { return _fields[i].Name; }
public object GetValue(int i){ return _fields[i].GetValue(_asychEnumerator.Current); }
}
我仍在研究该示例,但对 Read() 方法的实现有些疑惑。
我有以下方法 returns 和 IAsyncEnumerable<T>
:
async IAsyncEnumerable<T> RunReport()
{
var handler = new HttpClientHandler();
var client = new HttpClient(handler);
client.BaseAddress = new Uri("");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var settings = new JsonSerializerSettings();
var jsonFormatter = new JsonMediaTypeFormatter() { SerializerSettings = settings };
var requestMessage = new HttpRequestMessage(HttpMethod.Get, "api/controler");
var response = await client.SendAsync(requestMessage);
response.EnsureSuccessStatusCode();
using (var stream = await response.Content.ReadAsStreamAsync())
{
using (var reader = new StreamReader(stream))
{
while (!reader.EndOfStream)
{
var linesJson = await reader.ReadLineAsync();
var line = JsonConvert.DeserializeObject<List<T>>(linesJson, jsonFormatter.SerializerSettings);
foreach (var line in lines)
yield return line;
}
}
}
}
我想使用 SqlBulkCopy
的 WriteToServerAsync
方法将该结果流式传输到数据库,但不知道如何将其转换为 IDataReader
或任何WriteToServerAsync
的重载列表中的其他类型。
我愿意使用批量复制以外的其他方式,前提是它具有合理的性能。
使用示例 here,我想出了一个 IDataReader,它采用 IAsyncEnumerable,并实现了接口的适当部分。
public class GenericDataReader<T> : IDataReader where T : class
{
private readonly IAsyncEnumerator<T> _asychEnumerator;
private readonly List<FieldInfo> _fields = new List<FieldInfo>();
public GenericDataReader(IAsyncEnumerable<T> asyncEnumerable)
{
_asychEnumerator = asyncEnumerable.GetAsyncEnumerator();
foreach (FieldInfo fieldinfo in typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public))
{
_fields.Add(fieldinfo);
}
}
public int FieldCount => _fields.Count;
public void Dispose() { Close(); }
public bool Read()
{
return _asycEnumerator.MoveNextAsync().Result;
}
public async void Close(){ await _asychEnumerator.DisposeAsync(); }
public Type GetFieldType(int i){ return _fields[i].FieldType; }
public string GetName(int i) { return _fields[i].Name; }
public object GetValue(int i){ return _fields[i].GetValue(_asychEnumerator.Current); }
}
我仍在研究该示例,但对 Read() 方法的实现有些疑惑。