/// <summary>
        /// Convertir el DataReader y la convierte en una lista del tipo <typeparamref name="T"/>
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="reader"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public virtual IEnumerable <T> ConvertirLoteDataReader <T>(IDataReader reader, HttpContextBase context) where T : CatalogoModel, new()
        {
            IEnumerable <SerieModel>   seriesList   = new SeriesDataService().ObtenerSeries(null, null, context);
            IEnumerable <MateriaModel> materiasList = new MateriasDataService().ObtenerMaterias(null, null, context);
            List <T> modelos = new List <T>();
            DataSet  ds      = ((ExcelDataReader.IExcelDataReader)reader).AsDataSet(new ExcelDataSetConfiguration()
            {
                ConfigureDataTable = (rowReader) =>
                                     new ExcelDataTableConfiguration()
                {
                    UseHeaderRow = true
                }
            });

            using (DataTableReader dsReader = ds.Tables[0].CreateDataReader())
                modelos = this.FillCatalogoListExcel <T>(dsReader, new SeriesDataService(), seriesList, new MateriasDataService(), materiasList, false, context);
            //this.InsertarLote(modelos, context);
            return(modelos);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="expr"></param>
        /// <param name="parameters"></param>
        /// <param name="page"></param>
        /// <param name="includeHist">0 = without Hist; 1 = with Hist; 2 = only Hist</param>
        /// <param name="context"></param>
        /// <returns></returns>
        public virtual IEnumerable <CatalogoModel> GetCatalogos(QueryExpresion expr, Dictionary <string, object> parameters, long?page, byte includeHist, bool limitarStrings, HttpContextBase context)
        {
            SeriesDataService        ds         = new SeriesDataService();
            IEnumerable <SerieModel> seriesList = ds.ObtenerSeries(null, null, context);
            List <CatalogoModel>     read       = new List <CatalogoModel>();

            switch (includeHist)
            {
            case 0:     //sin hist
                read = this.GetOrCreateValue <List <CatalogoModel> >(
                    this.GetOrCreateKey(context),
                    () => this.FillCatalogoList(DataConnection.Instance.ExecuteQuery(
                                                    string.Format(SqlResource.SqlCatalogoResource, expr?.ToString() ?? "1=1"),
                                                    parameters,
                                                    context,
                                                    page.GetValueOrDefault(1)), seriesList, limitarStrings)
                    , "GetCatalogos", 0, expr?.ToString(), parameters, page.GetValueOrDefault(1)
                    );
                break;

            case 1:     //ambos
                read = this.GetOrCreateValue(
                    this.GetOrCreateKey(context),
                    () => this.FillCatalogoList(DataConnection.Instance.ExecuteQuery(
                                                    string.Format(SqlResource.SqlCatalogoAmbosResource, expr?.ToString() ?? "1=1"),
                                                    parameters,
                                                    context,
                                                    page.GetValueOrDefault(1)), seriesList, limitarStrings)
                    , "GetCatalogos", 1, expr?.ToString(), parameters, page.GetValueOrDefault(1)
                    );
                break;

            case 2:     //solo hist
                read = this.GetOrCreateValue <List <HistCatalogoModel> >(
                    this.GetOrCreateKey(context),
                    () => this.FillHistCatalogoList(DataConnection.Instance.ExecuteQuery(string.Format(SqlResource.SqlHistCatalogoResource, expr?.ToString() ?? "1=1"), parameters, context, page.GetValueOrDefault(1)), seriesList, limitarStrings)
                    , "GetCatalogos", 2, expr?.ToString(), parameters, page.GetValueOrDefault(1)
                    ).Cast <CatalogoModel>().ToList();
                break;
            }
            return(read);
        }
        protected virtual List <T> FillCatalogoListExcel <T>(IDataReader reader, SeriesDataService serieDs, IEnumerable <SerieModel> seriesList, MateriasDataService materiaDs, IEnumerable <MateriaModel> materiasList, bool limitarStrings, HttpContextBase context) where T : CatalogoModel, new()
        {
            List <T> result = new List <T>();
            long     count  = 0;

            while (reader.Read())
            {
                T nc = new T();
                //--------------------------\\
                nc.Contenido = Convert.IsDBNull(reader["Contenido"]) ? null : reader["Contenido"].ToString();
                nc.Año       = Convert.IsDBNull(reader["Año"]) ? (short?)null : Convert.ToInt16(reader["Año"]); //Año
                nc.Fecha     = Convert.IsDBNull(reader["Fecha"]) ? (DateTime?)null : (DateTime)reader["Fecha"];
                nc.Folio     = Convert.IsDBNull(reader["Folio"]) ? null : reader["Folio"].ToString();

                if (seriesList.Count() > 0)
                {
                    SerieModel serie = seriesList.FirstOrDefault(sm => sm.Nombre.Trim().Equals(reader["Series"].ToString().Trim()));
                    if (serie == null)
                    {
                        serie = new SerieModel()
                        {
                            Nombre = reader["Series"].ToString()
                        };
                        serieDs.Insertar(serie, context);
                    }
                    nc.IdSerie      = serie?.ID;
                    nc.SeriesNombre = serie?.Nombre;
                }

                if (materiasList.Count() > 0)
                {
                    string materiaExt = Convert.IsDBNull(reader["Materias"]) ? null : reader["Materias"].ToString();
                    if (!string.IsNullOrEmpty(materiaExt))
                    {
                        nc.ListaMaterias = new List <MateriaModel>();
                        string[] valoresSeparados = null;
                        if (materiaExt.Contains(" / "))
                        {
                            valoresSeparados = materiaExt.Split(new string[] { " / " }, StringSplitOptions.RemoveEmptyEntries);
                        }
                        else
                        {
                            valoresSeparados = new string[] { materiaExt };
                        }
                        foreach (string item in valoresSeparados)
                        {
                            MateriaModel materia = materiasList.FirstOrDefault(m => m.Nombre.Trim().Equals(item.Trim()));
                            if (materia == null)
                            {
                                materia = new MateriaModel()
                                {
                                    Nombre = item
                                };
                                materiaDs.Insertar(materia, context);
                            }
                            nc.ListaMaterias.Add(materia);
                        }
                    }
                }

                nc.Libro         = Convert.IsDBNull(reader["Libro"]) ? (int?)null : Convert.ToInt32(reader["Libro"]);
                nc.Lugar         = Convert.IsDBNull(reader["Lugar"]) ? null : reader["Lugar"].ToString();
                nc.NumCaja       = Convert.IsDBNull(reader["Caja"]) ? null : reader["Caja"].ToString();
                nc.NumCarpeta    = Convert.IsDBNull(reader["Carpeta"]) ? (int?)null : Convert.ToInt32(reader["Carpeta"]);
                nc.NumExpediente = Convert.IsDBNull(reader["Expediente"]) ? null : reader["Expediente"].ToString();
                nc.NumTomo       = Convert.IsDBNull(reader["Tomo"]) ? (int?)null : Convert.ToInt32(reader["Tomo"]);
                nc.Observaciones = Convert.IsDBNull(reader["Observaciones"]) ? null : reader["Observaciones"].ToString();
                //nc.Materias = Convert.IsDBNull(reader["Materias"]) ? null : reader["Materias"].ToString();
                nc.Origen = 1;
                nc.ID     = count++;
                //--------------------------\\
                result.Add(nc);
            }
            return(result);
        }
        public virtual CatalogoModel GetCatalogo(QueryExpresion expr, Dictionary <string, object> parameters, bool paraEditar, byte includeHist, HttpContextBase context)
        {
            SeriesDataService ds   = new SeriesDataService();
            var         seriesList = ds.ObtenerSeries(null, null, context);
            IDataReader read;

            switch (includeHist)
            {
            case 0:     //sin hist
                read = DataConnection.Instance.ExecuteQuery(
                    string.Format(SqlResource.SqlCatalogoResource, expr?.ToString() ?? "1=1"),
                    parameters,
                    context, 0);
                if (read.Read())
                {
                    CatalogoModel nc = new CatalogoModel();
                    nc.Fill(read);
                    if (seriesList.Count() > 0)
                    {
                        nc.SeriesNombre = seriesList.FirstOrDefault(sm => sm.ID == nc.IdSerie.GetValueOrDefault(0))?.Nombre;
                    }
                    nc.EstablecerSignaturaPorDefecto();
                    nc.ListaMaterias = !paraEditar?this.ObtenerMateriasDeCatalogo(nc.ID, context) : null;

                    nc.ListaMateriasSeleccionables = paraEditar ? this.ObtenerMateriasSeleccionablesDeCatalogo(nc.ID, context) : null;
                    nc.ListaLugares = this.ObtenerLugaresDeCatalogo(nc.ID, context);
                    nc.Origen       = 0;
                    return(nc);
                }
                break;

            case 1:
                read = DataConnection.Instance.ExecuteQuery(
                    string.Format(SqlResource.SqlCatalogoAmbosResource, expr?.ToString() ?? "1=1"),
                    parameters,
                    context, 0);
                if (read.Read())
                {
                    int           origen = (int)read.GetInt64(read.GetOrdinal("Hist"));
                    CatalogoModel nc     = new CatalogoModel();
                    nc.Fill(read);
                    if (seriesList.Count() > 0)
                    {
                        nc.SeriesNombre = seriesList.FirstOrDefault(sm => sm.ID == nc.IdSerie.GetValueOrDefault(0))?.Nombre;
                    }
                    nc.EstablecerSignaturaPorDefecto();
                    nc.Origen = origen == 0 ? (byte)0 : (byte)2;
                    if (origen == 0)
                    {
                        nc.ListaMaterias = !paraEditar?this.ObtenerMateriasDeCatalogo(nc.ID, context) : null;

                        nc.ListaMateriasSeleccionables = paraEditar ? this.ObtenerMateriasSeleccionablesDeCatalogo(nc.ID, context) : null;
                        nc.ListaLugares = this.ObtenerLugaresDeCatalogo(nc.ID, context);
                    }
                    return(nc);
                }
                break;

            case 2:    //solo hist
                read = DataConnection.Instance.ExecuteQuery(
                    string.Format(SqlResource.SqlHistCatalogoResource, expr?.ToString() ?? "1=1"),
                    parameters,
                    context, 0);

                if (read.Read())
                {
                    HistCatalogoModel nc = new HistCatalogoModel();
                    nc.Fill(read);
                    if (seriesList.Count() > 0)
                    {
                        nc.SeriesNombre = seriesList.FirstOrDefault(sm => sm.ID == nc.IdSerie.GetValueOrDefault(0))?.Nombre;
                    }
                    if (string.IsNullOrEmpty(nc.Signatura))
                    {
                        nc.EstablecerSignaturaPorDefecto();
                    }
                    return(nc);
                }
                break;
            }
            return(null);
        }