Aquí está el problema:
Tengo que devolver una colección de objetos con filtrado anidada colecciones.
E. g: hay una tienda con los pedidos y tengo que devolver una colección de tiendas que incluye anidada colecciones con las órdenes, pero sin los pedidos de los clientes que están marcados como eliminados.

Aquí es lo que quiero hacer. Pero no ha habido suerte. Cualquier sugerencias se agradecen 🙂

public List<StoreEntity> GetStores(Func<Store, bool> storeFilter, Predicate<OrderEntity> orderFileter)
{
    IQueryable<StoreEntity> storeEntities = Context.Stores
        .Include(o => o.Order)
        .Include(cu => cu.Orders.Select(c => c.Customer))
        .Where(storeFilter)
        //.Where(rcu=>rcu.Orders.Select(cu=>cu.Customer.Deleted==false)) //just test this doesn't work
        .AsQueryable();

    List<StoreEntity> storeEntities = storeEntities.ToList();

    //storeEntities.ForEach(s => s.Orders.ToList().RemoveAll(c=>c.Customer.Deleted==true)); //doesn't work

    foreach (StoreEntity storeEntity in storeEntities)
    {
        storeEntity.Orders.ToList().RemoveAll(r=>r.Customer.Deleted==true);
    }

    return storeEntities;
}

El problema es que el filtro no se aplica. Los clientes que han eliminado la bandera establece como verdadera estancia en la colección.

  • Y ¿cuál es el problema? No se compile? Qué lanzar una excepción en tiempo de ejecución? Funciona bien pero el regreso de los datos erróneos?
  • explica un poco más. thx.
  • Terminé usando este paquete de nuget: Z.EntityFramework.Plus.QueryIncludeFilter.EF6 Documentación aquí: github.com/zzzprojects/EntityFramework-Plus/wiki/…
  • Este paquete de Nuget deben ser aceptados como una respuesta, no un comentario!
InformationsquelleAutor Nazar Gargol | 2011-08-16

3 Comentarios

  1. 31

    Usted no puede hacerlo directamente en una «limpia», sino que tiene un par de opciones.

    Primero de todos, usted puede explícitamente de carga de la colección infantil después de haber obtenido los almacenes. Ver el La aplicación de filtros cuando explícitamente relacionados con la carga de las entidades sección.

    Si usted no quiere hacer más viajes a la base de datos, usted tendrá que construir su propia consulta y proyecto de la colección principal y el filtrado niño colecciones en otro objeto de forma manual. Vea las siguientes preguntas para ejemplos:

    Linq To entities – cómo filtrar por niño entidades

    Consulta LINQ – cómo ordenar y filtrar con ganas de captura

    Editar

    Por el camino, su primer .Where(rcu=>rcu.Orders.Select(cu=>cu.Customer.Deleted==false)) intento no funciona ya que de esta manera se está aplicando un filtro a la colección principal (tiendas) en lugar de la misma colección (por ejemplo, todas las tiendas que no han eliminado los clientes).

    Lógicamente, el código de filtrado de la misma colección debe ser colocado en la Include método. En la actualidad, Include sólo admite un Select declaración, pero personalmente creo que es hora de que el equipo EF implementar algo como:

    .Include(cu => cu.Orders.Select(c => c.Customers.Where(cust => !cust.IsDeleted)));
    • Sí, estoy de acuerdo. (Sé que la cosa no funciona, pero aún así quería probarlo, quién sabe, tal vez esa característica estaba oculto y me habría sorprendido gratamente), y sí, este tipo de Incluir sería bueno tener. Me decidí a ir con la costumbre de proyección… no me gusta ese método porque tenía que asignar un montón de tontos valores similares ( ID= r.ID, Name= r.Nombre … y así sucesivamente). Pero al menos funciona 🙂 Thx
    • Estoy de acuerdo en el equipo EF debe aplicar filtrados Incluyen. A votar por ella aquí!
    • ¿Qué pasa si tengo un método genérico llamado GetWithInclude() public IQueryable<TEntity> GetWithInclude(params Expression<Func<TEntity, object>>[] includeProperties) { return includeProperties.Aggregate<Expression<Func<TEntity, object>>, IQueryable<TEntity>>(DbSet, (current, includeProperty) => current.Include(includeProperty)); } sin Embargo, no tengo una colección y necesito el filtro de una proyección. En otras palabras, tengo una propiedad que necesita para la igualdad de algo.
  2. 3

    El problema con el código que tiene actualmente se esta línea:

    storeEntity.Orders.ToList().RemoveAll(r=>r.Customer.Deleted==true);

    storeEntity.Orders.ToList() devuelve un nueva List<OrderEntity> con el contenido de storeEntity.Orders. A partir de esta nueva lista, quitar eliminados todos los clientes. Sin embargo, esta lista no es utilizado en cualquier lugar después de que.

    Sin embargo, incluso si se iba a hacer lo que desea, esto también eliminar aquellos clientes de la base de datos, debido a que su StoreEntity objetos están todavía conectados a los datos de contexto!

    Usted realmente desea utilizar un filtro como se trató en el comentado Where. Por favor, consulte Yakimych la respuesta para ayudar en eso.

  3. -6

    Viejo tema, pero me encontré en una situación similar. He buscado mucho, y la MSDN enlace proporcionado por Yakimych finalmente dejó entrever que me de una solución : explicitamente deshabilitar la carga diferida, y, a continuación, hacer consultas para filtrar las propiedades de navegación. El resultado será entonces «conectado» a la consulta principal, lo que le daría algo así como que :

    Context.Configuration.LazyLoadingEnabled = false;
    
    var filteredOrders = Context.Orders.Where(x => x.Customer.Delete == false);
    
    IQueryable<StoreEntity> storeEntities = Context.Stores
    .Include(o => o.Order)
    .Include(cu => cu.Orders.Select(c => c.Customer))
    .Where(storeFilter)
    .AsQueryable();
    • ¿Qué es storeFilter ?

Dejar respuesta

Please enter your comment!
Please enter your name here