using System; using System.Collections.Generic; using System.Data; using System.Diagnostics.CodeAnalysis; namespace Kit.Helpers.SqlHelperAbstract { public interface IDataRecordSpecified { IDataReader Src { get; } Npgsql.INpgsqlNameTranslator NameTranslator { get; } TValue Convert(object value); } internal class DataRecordSpecified : IDataRecordSpecified { public IDataReader Src { get; } public Npgsql.INpgsqlNameTranslator NameTranslator { get; } public virtual TValue Convert(object value) { return (TValue)value; } public DataRecordSpecified(IDataReader dataReader, Npgsql.INpgsqlNameTranslator nameTranslator) { Src = dataReader; NameTranslator = nameTranslator; } } public static class DataRecordSpecifiedExtensions { /// /// Проверка на наличие столбца в запросе /// /// /// /// public static bool HasColumn(this IDataRecordSpecified reader, string name) { string nameTranslated = reader.NameTranslator.TranslateMemberName(name).ToLower(); for (int n = 0; n < reader.Src.FieldCount; n++) { string fieldNameTranslated = reader.NameTranslator.TranslateMemberName(reader.Src.GetName(n)).ToLower(); if (fieldNameTranslated == nameTranslated) return true; } return false; } private static string GetTranslatedName(this IDataRecordSpecified record, string fieldName) => record.NameTranslator.TranslateMemberName(fieldName); #if NETFRAMEWORK private static TValue TryGet(this IDataRecordSpecified record, string fieldName, bool isStrict) #elif NETCOREAPP private static TValue? TryGet(this IDataRecordSpecified record, string fieldName, bool isStrict) #endif { fieldName = GetTranslatedName(record, fieldName); object value = record.Src[fieldName]; if (value == DBNull.Value) { if (isStrict) throw new InvalidCastException(string.Format("{0} {1} нельзя привести к {2}", fieldName, typeof(DBNull).FullName, typeof(TValue).FullName)); return default; } try { return record.Convert(value); } catch (InvalidCastException ex) { throw new InvalidCastException(string.Format("{0} {1} нельзя привести к {2}", fieldName, value.GetType().FullName, typeof(TValue).FullName), ex); } } public static bool IsDbNull(this IDataRecordSpecified record, string fieldName) => record.Src[fieldName] == DBNull.Value; public static bool IsNotDbNull(this IDataRecordSpecified record, string fieldName) => !record.IsDbNull(fieldName); public static TValue Get(this IDataRecordSpecified record, string fieldName) => record.TryGet(fieldName, isStrict: true); #if NETFRAMEWORK public static TValue GetN(this IDataRecordSpecified record, string fieldName) #elif NETCOREAPP public static TValue? GetN(this IDataRecordSpecified record, string fieldName) #endif => record.TryGet(fieldName, isStrict: false); internal static void ProcessExtraSelect(this IDataRecordSpecified readerSpecified, IList selectResult, SelectType extraSelectType = SelectType.Default) { switch (extraSelectType) { case SelectType.Page: { var result = (IEnumerableWithPage)selectResult; // считывание данных постраничного вывода while (readerSpecified.Src.Read()) { if (readerSpecified.HasColumn("FilteredRows")) result.FilterRow = readerSpecified.Get("filteredRows"); if (readerSpecified.HasColumn("TotalRows")) result.TotalRows = readerSpecified.Get("totalRows"); if (readerSpecified.HasColumn("PageNo")) result.PageNo = readerSpecified.Get("pageNo"); if (readerSpecified.HasColumn("PageSize")) result.PageSize = readerSpecified.Get("pageSize"); if (readerSpecified.HasColumn("Sort")) result.Sort = readerSpecified.Get("sort"); //if (readerSpecified.HasColumn("Dir")) result.Dir = readerSpecified.Get("dir"); } } break; case SelectType.Offer: { var result = (IEnumerableWithOffer)selectResult; // считывание данных постраничного вывода while (readerSpecified.Src.Read()) { if (readerSpecified.HasColumn("FilteredRows")) result.FilterRow = readerSpecified.Get("FilteredRows"); if (readerSpecified.HasColumn("TotalRows")) result.TotalRows = readerSpecified.Get("TotalRows"); if (readerSpecified.HasColumn("Start")) result.Start = readerSpecified.Get("Start"); if (readerSpecified.HasColumn("Length")) result.Lenght = readerSpecified.Get("Length"); if (readerSpecified.HasColumn("Sort")) result.Sort = readerSpecified.Get("Sort"); //if (readerSpecified.HasColumn("Dir")) result.Dir = readerSpecified.Get("Dir"); } } break; case SelectType.Default: default: break; } } } }