Crear una instrucción LINQ dinámica sin tener una propiedad de tipo de entidad
-
06-07-2019 - |
Pregunta
Estoy intentando crear una declaración Linq que consulta las dos columnas que existen en mi entidad como propiedades y las que no existen, pero existen como columnas en la base de datos para la entidad.
Por ejemplo, tengo una colección de entidades de libros. Cada libro tiene una identificación y propiedad de título y una columna coincidente en la base de datos. Pero, digamos que la tabla para Libro también contiene un campo de columna para Autor y la entidad de Mi Libro no tiene esto.
Una consulta normal que incluya el ID y el Título podría tener este aspecto:
Books.Where(b=>b.ID == 123 && b.Title == "Title")
Pero, también quiero agregar dinámicamente el equivalente de " AND Autor = 'Nombre' " a la consulta anterior también. La propiedad Autor no existe en el objeto Libro.
Los campos adicionales y los valores que deben contener realmente estarán disponibles en un Diccionario. Así que tendré que agregar dinámicamente varias condiciones AND [FieldName] = '[Value]' a la consulta.
Podría ayudar a explicar por qué necesitaría esto para saber que estoy usando Azure Table Storage y he anulado la serialización que convierte una entidad de Libro en el XML almacenado en Azure.
Editar -
He intentado usar la biblioteca Dynamic Linq pero no funciona.
Books.Where(b=>b.ID == 123 && b.Title == "Title").Where("Author = @0", "SomeName").ToList();
arroja: System.Linq.Dynamic.ParseException: No existe ninguna propiedad o campo 'Autor' en el tipo 'Libro'.
También,
Sé que utilizando Books.AddQueryOption (" $ filter ", " Autor eq 'SomeName' ") funciona cuando se usa solo. Pero no tengo idea de cómo usar AddQueryOption junto con una declaración Where existente.
Solución 2
Esto no es posible con LINQ
Otros consejos
Sin agregar Author to Book, tendría que pasar otro objeto con Author en él:
var x = new { Author="SomeName" };
Books.Where(b=>b.Id == 1 && b.Title == "Alpha").Where("@1.Author == @0", "SomeName", x);
O herede de Libro y agrega una propiedad de Autor solo para este propósito:
public class BookEx : Book {
public string Author { get; set; }
}
Books.Cast<BookEx>().Where(b=>b.Id == 1 && b.Title== "Alpha").Where("Author == @0", "SomeName");
Eche un vistazo a la biblioteca Dynamic Linq
Prueba el siguiente código:
var result = _tofiObjectList.Where(o => o.GetType() == mainObjType)
.AsQueryable().Cast(relation.MainObject.EntityType).Where(relation.MainObject.Filter);
Este es un método de extensión para el tipo IQueryable
:
public static IQueryable Cast(this IQueryable source, string type)
{
switch (type)
{
case "TofiDataCollection.Service.TofiEntity.Obj":
return source.Cast<Obj>();
}
return source;
}