123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507 |
- using EasyDevCore.Database;
- using EasyDevCore.Database.EntityTable;
- using EasyDevCore.Common;
- using System.Data;
- using System.Data.Common;
- using System.Dynamic;
- using System.Text;
- namespace EasyDevCore.Database
- {
- /// <summary>
- ///
- /// </summary>
- public static class DbDataReaderExtensions
- {
- /// <summary>
- /// Gets the value.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="reader">The reader.</param>
- /// <param name="fieldName">Name of the field.</param>
- /// <param name="valueIfNull">The value if null.</param>
- /// <returns></returns>
- public static T GetValue<T>(this DbDataReader reader, string fieldName, T valueIfNull)
- {
- int colIndex = reader.GetOrdinal(fieldName);
- object value = reader.GetValue(colIndex);
- if (value == null) return valueIfNull;
- Type columnType = reader.GetFieldType(colIndex);
- if (typeof(T) == columnType)
- {
- return (T)value;
- }
- else
- {
- return (T)Convert.ChangeType(value, columnType);
- }
- }
- /// <summary>
- /// Gets the row.
- /// </summary>
- /// <param name="reader">The reader.</param>
- /// <returns></returns>
- public static dynamic GetRow(this DbDataReader reader)
- {
- IDictionary<string, object> expandoObject = new ExpandoObject() as IDictionary<string, object>;
- var fieldCount = reader.FieldCount;
- for (var i = 0; i < fieldCount; i++)
- expandoObject.Add(reader.GetName(i), reader.IsDBNull(i) ? null : reader[i]);
- return expandoObject;
- }
- /// <summary>
- /// Gets the row asynchronous.
- /// </summary>
- /// <param name="reader">The reader.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns></returns>
- public static async Task<dynamic> GetRowAsync(this DbDataReader reader, CancellationToken cancellationToken)
- {
- var expandoObject = new ExpandoObject() as IDictionary<string, object>;
- for (var i = 0; i < reader.FieldCount; i++)
- {
- object value = await reader.IsDBNullAsync(i, cancellationToken).ConfigureAwait(false) ? null : reader.GetValue(i);
- expandoObject.Add(reader.GetName(i), value);
- }
- return expandoObject;
- }
- /// <summary>
- /// Fetches to json.
- /// </summary>
- /// <param name="reader">The reader.</param>
- /// <param name="indentFormat">if set to <c>true</c> [indent format].</param>
- /// <returns></returns>
- public static string FetchToJson(this DbDataReader reader, bool indentFormat = false)
- {
- if (reader.IsClosed) return null;
- var JSONString = new StringBuilder();
- if (indentFormat)
- {
- JSONString.AppendLine("[");
- while (reader.Read())
- {
- JSONString.AppendLine("{");
- for (int i = 0; i < reader.FieldCount; i++)
- {
- string value = "\"" + reader.GetName(i) + "\":"
- + (reader.IsDBNull(i) ? "null" :
- "\"" + System.Web.HttpUtility.JavaScriptStringEncode(reader[i].StringFrom()) + "\""
- );
- if (i < reader.FieldCount - 1)
- {
- value += ",";
- }
- JSONString.AppendLine(value);
- }
- JSONString.AppendLine("}");
- }
- JSONString.AppendLine("]");
- }
- else
- {
- JSONString.Append("[");
- while (reader.Read())
- {
- JSONString.Append("{");
- for (int i = 0; i < reader.FieldCount; i++)
- {
- string value = "\"" + reader.GetName(i) + "\":"
- + (reader.IsDBNull(i) ? "null" :
- "\"" + System.Web.HttpUtility.JavaScriptStringEncode(reader[i].StringFrom()) + "\""
- );
- if (i < reader.FieldCount - 1)
- {
- value += ",";
- }
- JSONString.Append(value);
- }
- JSONString.Append("}");
- }
- JSONString.Append("]");
- }
- return JSONString.ToString();
- }
- /// <summary>
- /// Fetches to json asynchronous.
- /// </summary>
- /// <param name="reader">The reader.</param>
- /// <param name="indentFormat">if set to <c>true</c> [indent format].</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns></returns>
- public static async Task<string> FetchToJsonAsync(this DbDataReader reader, bool indentFormat = false, CancellationToken cancellationToken = default)
- {
- if (reader.IsClosed) return null;
- var JSONString = new StringBuilder();
- if (indentFormat)
- {
- JSONString.AppendLine("[");
- while (await reader.ReadAsync(cancellationToken).ConfigureAwait(false))
- {
- JSONString.AppendLine("{");
- for (int i = 0; i < reader.FieldCount; i++)
- {
- string value = "\"" + reader.GetName(i) + "\":"
- + (await reader.IsDBNullAsync(i, cancellationToken).ConfigureAwait(false) ? "null" : "\"" +
- System.Web.HttpUtility.JavaScriptStringEncode(reader[i].StringFrom()) + "\"");
- if (i < reader.FieldCount - 1)
- {
- value += ",";
- }
- JSONString.AppendLine(value);
- }
- JSONString.AppendLine("}");
- }
- JSONString.AppendLine("]");
- }
- else
- {
- JSONString.Append("[");
- while (await reader.ReadAsync(cancellationToken).ConfigureAwait(false))
- {
- JSONString.Append("{");
- for (int i = 0; i < reader.FieldCount; i++)
- {
- string value = "\"" + reader.GetName(i) + "\":"
- + (await reader.IsDBNullAsync(i, cancellationToken).ConfigureAwait(false) ? "null" : "\"" +
- System.Web.HttpUtility.JavaScriptStringEncode(reader[i].StringFrom()) + "\"");
- if (i < reader.FieldCount - 1)
- {
- value += ",";
- }
- JSONString.Append(value);
- }
- JSONString.Append("}");
- }
- JSONString.Append("]");
- }
- return JSONString.ToString();
- }
- /// <summary>
- /// Fetches to list.
- /// </summary>
- /// <param name="reader">The reader.</param>
- /// <returns></returns>
- public static IList<dynamic> FetchToDynamic(this DbDataReader reader)
- {
- if (reader.IsClosed) return null;
- List<dynamic> list = new();
- while (reader.Read())
- {
- list.Add(reader.GetRow());
- }
- return list;
- }
- /// <summary>
- /// Fetches to dynamic asynchronous.
- /// </summary>
- /// <param name="reader">The reader.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns></returns>
- public static async Task<IList<dynamic>> FetchToDynamicAsync(this DbDataReader reader, CancellationToken cancellationToken = default)
- {
- if (reader.IsClosed) return null;
- List<dynamic> list = new();
- DataRecordDynamic wrapper = new(reader);
- while (await reader.ReadAsync(cancellationToken).ConfigureAwait(false))
- {
- list.Add(await reader.GetRowAsync(cancellationToken).ConfigureAwait(false));
- }
- bool hasNextResult = await reader.NextResultAsync(cancellationToken).ConfigureAwait(false);
- if (!hasNextResult) await reader.CloseAsync().ConfigureAwait(false);
- return list;
- }
- /// <summary>
- /// Fetches the fill list internal.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="reader">The reader.</param>
- /// <param name="list">The list.</param>
- /// <returns></returns>
- private static IList<T> FetchFillListInternal<T>(this DbDataReader reader, IList<T> list)
- where T : class, new()
- {
- if (reader.IsClosed) return null;
- var mapper = new DbDataReaderMapper<T>(reader);
- mapper.Map(row => list.Add(row));
- bool hasNextResult = reader.NextResult();
- if (!hasNextResult) reader.Close();
- return list;
- }
- /// <summary>
- /// Fetches the fill list internal asynchronous.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="reader">The reader.</param>
- /// <param name="list">The list.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns></returns>
- private async static Task<IList<T>> FetchFillListInternalAsync<T>(this DbDataReader reader, IList<T> list, CancellationToken cancellationToken = default)
- where T : class, new()
- {
- if (reader.IsClosed) return null;
- var mapper = new DbDataReaderMapper<T>(reader);
- await mapper.MapAsync(row => list.Add(row), cancellationToken).ConfigureAwait(false);
- bool hasNextResult = await reader.NextResultAsync(cancellationToken).ConfigureAwait(false);
- if (!hasNextResult) await reader.CloseAsync().ConfigureAwait(false);
- return list;
- }
- /// <summary>
- /// Fetches the fill list.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="reader">The reader.</param>
- /// <param name="list">The list.</param>
- /// <returns></returns>
- public static int FetchFillList<T>(this DbDataReader reader, IList<T> list)
- where T : class, new()
- {
- int rowsCount = list.Count;
- return reader.FetchFillListInternal(list).Count - rowsCount;
- }
- /// <summary>
- /// Fetches the fill list asynchronous.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="reader">The reader.</param>
- /// <param name="list">The list.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns></returns>
- public static async Task<int> FetchFillListAsync<T>(this DbDataReader reader, IList<T> list, CancellationToken cancellationToken = default)
- where T : class, new()
- {
- int rowsCount = list.Count;
- return (await reader.FetchFillListInternalAsync(list, cancellationToken).ConfigureAwait(false)).Count - rowsCount;
- }
- /// <summary>
- /// Fetches to list.
- /// </summary>
- /// <typeparam name="TResult">The type of the result.</typeparam>
- /// <param name="reader">The reader.</param>
- /// <param name="selector">The selector.</param>
- /// <returns></returns>
- public static IList<TResult> FetchToList<TResult>(this DbDataReader reader, Func<dynamic, TResult> selector)
- {
- if (reader.IsClosed) return null;
- List<TResult> list = new();
- DataRecordDynamic wrapper = new(reader);
- while (reader.Read())
- {
- var item = selector(wrapper);
- list.Add(item);
- }
- bool hasNextResult = reader.NextResult();
- if (!hasNextResult) reader.Close();
- return list;
- }
- /// <summary>
- /// Fetches to list asynchronous.
- /// </summary>
- /// <typeparam name="TResult">The type of the result.</typeparam>
- /// <param name="reader">The reader.</param>
- /// <param name="selector">The selector.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns></returns>
- public static async Task<IList<TResult>> FetchToListAsync<TResult>(this DbDataReader reader, Func<dynamic, TResult> selector, CancellationToken cancellationToken = default)
- {
- if (reader.IsClosed) return null;
- List<TResult> list = new();
- DataRecordDynamic wrapper = new(reader);
- while (await reader.ReadAsync(cancellationToken).ConfigureAwait(false))
- {
- var item = selector(wrapper);
- list.Add(item);
- }
- bool hasNextResult = await reader.NextResultAsync(cancellationToken).ConfigureAwait(false);
- if (!hasNextResult) await reader.CloseAsync().ConfigureAwait(false);
- return list;
- }
- /// <summary>
- /// Fetches to list.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="reader">The reader.</param>
- /// <param name="list">The list.</param>
- /// <returns></returns>
- public static IList<T> FetchToList<T>(this DbDataReader reader, IList<T> list = null)
- where T : class, new()
- {
- if (reader.IsClosed) return list;
- IList<T> listNew = list ?? new List<T>();
- listNew.Clear();
- return reader.FetchFillListInternal(listNew);
- }
- /// <summary>
- /// Fetches to list asynchronous.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="reader">The reader.</param>
- /// <param name="list">The list.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns></returns>
- public static async Task<IList<T>> FetchToListAsync<T>(this DbDataReader reader, IList<T> list = null, CancellationToken cancellationToken = default)
- where T : class, new()
- {
- if (reader.IsClosed) return list;
- IList<T> listNew = list ?? new List<T>();
- listNew.Clear();
- return await reader.FetchFillListInternalAsync(listNew, cancellationToken).ConfigureAwait(false);
- }
- /// <summary>
- /// Fetches the fill data set.
- /// </summary>
- /// <param name="reader">The reader.</param>
- /// <param name="dataSet">The data set.</param>
- public static int FetchFillDataSet(this DbDataReader reader, DataSet dataSet)
- {
- if (dataSet.Tables.Count == 0) return 0;
- var totalRows = dataSet.Tables.Cast<DataTable>().Sum(tb => tb.Rows.Count);
- int i = 0;
- do
- {
- dataSet.Tables[i].Load(reader);
- i++;
- } while (dataSet.Tables.Count > i && !reader.IsClosed);
- return dataSet.Tables.Cast<DataTable>().Sum(tb => tb.Rows.Count) - totalRows;
- }
- /// <summary>
- /// Fetches the fill data set asynchronous.
- /// </summary>
- /// <param name="reader">The reader.</param>
- /// <param name="dataSet">The data set.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns></returns>
- public static async Task<int> FetchFillDataSetAsync(this DbDataReader reader, DataSet dataSet, CancellationToken cancellationToken = default)
- {
- if (dataSet.Tables.Count == 0) return 0;
- var totalRows = dataSet.Tables.Cast<DataTable>().Sum(tb => tb.Rows.Count);
- int i = 0;
- do
- {
- await dataSet.Tables[i].LoadAsync(reader, cancellationToken).ConfigureAwait(false);
- } while (dataSet.Tables.Count > i && !reader.IsClosed);
- return dataSet.Tables.Cast<DataTable>().Sum(tb => tb.Rows.Count) - totalRows;
- }
- // <summary>
- /// <summary>
- /// Fetches to data set.
- /// </summary>
- /// <param name="reader">The reader.</param>
- /// <param name="dataSet">The data set.</param>
- /// <param name="parameters">The parameters.</param>
- /// <returns></returns>
- public static DataSet FetchToDataSet(this DbDataReader reader, DataSet dataSet = null, EasyDbParameterCollection parameters = null)
- {
- if (dataSet != null) dataSet.Clear();
- DataSet newDataSet = dataSet ?? new DataSet();
- do
- {
- newDataSet.Tables.Add().Load(reader, LoadOption.Upsert);
- if (parameters != null)
- {
- var result = ParameterUtils.GatherOutputParameters(0, parameters);
- foreach (var item in result)
- {
- newDataSet.ExtendedProperties[item.Key] = item.Value;
- }
- }
- } while (!reader.IsClosed);
- return newDataSet;
- }
- /// <summary>
- /// Fetches to data set asynchronous.
- /// </summary>
- /// <param name="reader">The reader.</param>
- /// <param name="DataSet">The entity set.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns></returns>
- public static async Task<DataSet> FetchToDataSetAsync(this DbDataReader reader, DataSet DataSet = null, CancellationToken cancellationToken = default)
- {
- if (DataSet != null) DataSet.Clear();
- DataSet newDataSet = DataSet ?? new DataSet();
- do
- {
- await newDataSet.Tables.Add().LoadAsync(reader, cancellationToken).ConfigureAwait(false);
- } while (!reader.IsClosed);
- return newDataSet;
- }
- /// <summary>
- /// Fetches to table.
- /// </summary>
- /// <param name="reader">The reader.</param>
- /// <param name="table">The table.</param>
- /// <returns></returns>
- public static int FetchFillTable(this DbDataReader reader, DataTable table)
- {
- int totalRows = table.Rows.Count;
- table.Load(reader);
- return table.Rows.Count - totalRows;
- }
- /// <summary>
- /// Fetches to table.
- /// </summary>
- /// <param name="reader">The reader.</param>
- /// <param name="table">The table.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns></returns>
- public static async Task<int> FetchFillTableAsync(this DbDataReader reader, DataTable table, CancellationToken cancellationToken = default)
- {
- if (reader.IsClosed) return 0;
- int totalRows = table.Rows.Count;
- await table.LoadAsync(reader);
- return table.Rows.Count - totalRows;
- }
- /// <summary>
- /// Fetches to table.
- /// </summary>
- /// <param name="reader">The reader.</param>
- /// <param name="table">The table.</param>
- /// <returns></returns>
- public static DataTable FetchToTable(this DbDataReader reader, DataTable table = null)
- {
- if (table != null) table.Clear();
- DataTable newTable = table ?? new DataTable();
- newTable.Load(reader);
- return newTable;
- }
- /// <summary>
- /// Fetches to table asynchronous.
- /// </summary>
- /// <param name="reader">The reader.</param>
- /// <param name="table">The table.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns></returns>
- public static async Task<DataTable> FetchToTableAsync(this DbDataReader reader, DataTable table = null, CancellationToken cancellationToken = default)
- {
- if (table != null) table.Clear();
- DataTable newTable = table ?? new DataTable();
- await newTable.LoadAsync(reader, cancellationToken).ConfigureAwait(false);
- return newTable;
- }
- }
- }
|