es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cargar dinámicamente tablas desde Entity Framework con el nombre de las tablas como cadena de texto

Digamos que tengo una lista de cadenas que representan el nombre de las clases generadas con Entity Framework desde SQL Server:

public static List<string> tableList = new List<string>
{
    "aaa",
    "bbb",
    "ccc",
    "ddd",
    "eee"
};

Y quiero cargar datos de entidades:

DateTime fromDate = DateTime.MinValue;
DateTime toDate = DateTime.MaxValue;

using (var ctx = new MyEntities())
{
    IList<aaa> aa = ctx.aaa
                   .Where(a => a.date_added >= fromDate && 
                               a.date_added <= toDate)
                   .ToList();
}

Pero tendré que hacer esto con 20 o más tablas.

¿Hay alguna manera de hacerlo de forma dinámica? Por ejemplo:

Result res = new Result();

List<result> r = new List<result>();

foreach (string table in tableList)
{
    using (var ctx = new MyEntities())
    {
        IList<table> aa = ctx.table
                           .Where(a => a.date_added >= fromDate && 
                                       a.date_added <= toDate)
                           .ToList();

        res.quantity = aa.Count();
        res.title = table;
    }

    r.Add(res);
}

Todas las tablas necesarias tienen la columna date_added.

PD: Solo necesito contar cuántas filas hay en cada tabla para un período definido. Por ejemplo, en las tablas cliente, cliente, empleado: cuántos se registraron desde 2020 hasta 2021. Y mostraré el resultado:

json
{
"title": "Cliente",
"quantity": 19,
"from_date": "fecha_inicial",
"to_date": "fecha_final"
},
{
"title": "Cliente",
"quantity": 123,
"from_date": "fecha_inicial",
"to_date": "fecha_final"
},
{
"title": "Empleado",
"quantity": 31,
"from_date": "fecha_inicial",
"to_date": "fecha_final"
}

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Sí, puedes utilizar la reflexión para lograr esto de forma dinámica. Aquí tienes un ejemplo de cómo puedes modificar tu código para obtener el resultado deseado:

    List<string> tableList = new List<string>
    {
        "aaa",
        "bbb",
        "ccc",
        "ddd",
        "eee",
    };
    
    DateTime from_date = DateTime.MinValue;
    DateTime to_date = DateTime.MaxValue;
    
    List<result> r = new List<result>();
    
    foreach (string table in tableList)
    {
        Result res = new Result();
    
        using (var ctx = new MyEntities())
        {
            string entityTypeFullName = typeof(MyEntities).Namespace + "." + table;
            Type entityType = Type.GetType(entityTypeFullName);
    
            if (entityType != null && entityType.GetProperty("date_added") != null)
            {
                var query = ctx.Set(entityType)
                               .Where("date_added >= @0 && date_added <= @1", from_date, to_date);
    
                IList entities = Activator.CreateInstance(typeof(List<>).MakeGenericType(entityType)) as IList;
                query.GetType().GetMethod("Load")?.Invoke(query, new object[] { entities });
    
                res.quantity = entities.Count;
                res.title = table;
    
                r.Add(res);
            }
        }
    }
    

    Explicación:

    • Primero definimos la lista de nombres de las tablas y el rango de fechas que queremos consultar.
    • Dentro del bucle, creamos un nuevo objeto Result para almacenar la cantidad y el título de cada tabla.
    • Utilizando la reflexión, obtenemos el objeto Type de la clase entidad correspondiente al nombre de tabla actual. Construimos el nombre de tipo completo de la clase entidad concatenando el espacio de nombres de la clase MyEntities y el nombre de la tabla.
    • Verificamos si la clase entidad tiene la propiedad date_added antes de continuar.
    • Construimos dinámicamente la consulta utilizando el método Set y el método Where que toma el rango de fechas. También utilizamos la reflexión para crear una List del tipo de entidad actual utilizando la clase Activator.
    • Finalmente, invocamos el método Load del objeto de consulta generado dinámicamente para llenar la lista entities con los resultados coincidentes. Luego, actualizamos el objeto Result con la cantidad y el título, y lo agregamos a la lista de resultados r.

    Nota: La clase Result no se proporciona en la pregunta, por lo que debe ser definida de la siguiente manera:

    public class Result
    {
        public string title { get; set; }
        public int quantity { get; set; }
    }
    

    ¡Espero que esto te sea útil!

Comments are closed.