2010-08-17 17 views
6

Básicamente quiero unir dos Iqueryable a uno Iqueryable y luego devolver el conjunto de registros completo después de que termine el ciclo. Funciona perfectamente, pero al final mi objret no tiene nada, pero cuando depuro el bucle obj tengo algunos registros. WHT im haciendo malProblema al crear el objeto IQueryable <T> vacío

IQueryable<MediaType> objret = Enumerable.Empty<MediaType>().AsQueryable(); 
var typ = _db.MediaTypes.Where(e => e.int_MediaTypeId != 1 && e.int_MediaTypeId_FK == null).ToList(); 
for (int i = 0; i < typ.Count; i++) 
{ 
    IQueryable<MediaType> obj = _db.MediaTypes.Where(e => e.bit_IsActive == true && e.int_MediaTypeId_FK == typ[i].int_MediaTypeId); 
    IQueryable<MediaType> obj1 = _db.MediaTypes.Where(e => e.int_OrganizationId == Authorization.OrganizationID && e.bit_IsActive == true && e.int_MediaTypeId_FK == typ[i].int_MediaTypeId); 

    if (obj1.Count() > 0) 
     obj.Concat(obj1); 
    if(obj.Count() > 0) 
     objret.Concat(obj); 
} 
return objret; 

Respuesta

4

Al igual que los otros operadores de consulta, Concat no cambia la secuencia existente - devuelve una nueva secuencia .

Así pues, estas líneas:?

if (obj1.Count() > 0) 
    obj.Concat(obj1); 
if(obj.Count() > 0) 
    objret.Concat(obj); 

debe ser

if (obj1.Count() > 0) 
    objret = objret.Concat(obj1); 
if(obj.Count() > 0) 
    objret = objret.Concat(obj); 

No estoy seguro de lo bien IQueryable va a manejar esto, teniendo en cuenta que va a mezclar LINQ a SQL (tal vez Entidades) con Enumerable.AsQueryable, fíjate. Dado que ya está ejecutando las consultas en cierta medida debido a las llamadas Count(), ¿ha considerado construir un List<T>?

(No es necesario para ejecutar el Count() en absoluto - sólo llame List<T>.AddRange(obj1) y lo mismo para obj.)

Como se mencionó jeroenh, lo ideal sería bueno utilizar una solución que podría hacer que todo lo que el base de datos sin bucle en absoluto en su código C#.

+0

lo cambio para crear una lista y funciona Gracias. –

+0

Este enfoque genera 4 viajes de ida y vuelta a la base de datos para cada iteración en el for-loop ... Eso es un posible problema de rendimiento si me preguntas (aunque obviamente depende del tamaño real de la tabla, por supuesto). – jeroenh

+0

@jeroenh: Sí, estaba dando a entender que no necesita usar 'Count()' en absoluto. Lo aclararé. –

0

Creo que no deberías hacer esto con un bucle for. El código que publique irá al db por cada medio activo activo dos veces para obtener el conteo() y, adicionalmente, dos veces para obtener los resultados reales.

No es necesario verificar la propiedad Count(): la concatenación de conjuntos de resultados vacíos no tiene ningún efecto adicional.

Por otra parte, creo que lo que estamos tratando de lograr que se puede hacer con una sola consulta, algo a lo largo de las líneas (no probado):

 // build up the query 

     var rootTypes = _db.MediaTypes.Where(e => e.int_MediaTypeId != 1 && e.int_MediaTypeId_FK == null); 
     var activeChildren = _db.MediaTypes 
           .Where(e => e.bit_IsActive); 
     var activeChildrenForOrganization = _db.MediaTypes 
           .Where(e => e.int_OrganizationId == Authorization.OrganizationID && e.bit_IsActive); 

     var q = from types in rootTypes 
       join e in activeChildren 
       on types.int_MediaTypeId equals e.int_MediaTypeId_FK into joined1 
       join e in activeChildrenForOrganization 
       on types.int_MediaTypeId equals e.int_MediaTypeId_FK into joined2 
       select new {types, joined1, joined2}; 


     // evaluate the query and concatenate the results. 
     // This will only go to the db once 
     return q.ToList().SelectMany(x => x.joined1.Concat(x.joined2)); 
Cuestiones relacionadas