简体   繁体   English

如何使用 SqlBulkCopy 编写 IAsyncEnumerable

[英]How to use SqlBulkCopy to write an IAsyncEnumerable

I have the following method that returns an IAsyncEnumerable<T> :我有以下方法返回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;
            }
        }
    }
}

I would like to take that result stream it to the database, using SqlBulkCopy 's WriteToServerAsync method, but cannot figure out how to turn it into an IDataReader or any other type in the WriteToServerAsync 's overload list.我想使用SqlBulkCopyWriteToServerAsync方法将该结果流传输到数据库,但无法弄清楚如何将其转换为IDataReaderWriteToServerAsync的重载列表中的任何其他类型。

I'm open to using something other than bulk copy, provided it's reasonably performant.如果性能合理,我愿意使用批量复制以外的其他东西。

using the example here , I've come up with an IDataReader that takes a IAsyncEnumerable, and implements the appropriate portion of the interface.使用此处的示例,我想出了一个 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); }
}   

I'm still working through the example, but am a bit leary of the Read() method's implementation.我仍在研究这个例子,但对 Read() 方法的实现有点了解。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM