2009-10-07 16 views
37

¿Puedo hacer que mis objetos EF recuperen solo columnas específicas en el sql ejecutado? Si estoy ejecutando el siguiente código para recuperar objetos, ¿hay algo que pueda hacer para obtener solo ciertas columnas si lo quisiera?Solo obtenga columnas específicas

public IEnumerable<T> GetBy(Expression<Func<T, bool>> exp) 
{ 
    return _ctx.CreateQuery<T>(typeof(T).Name).Where<T>(exp); 
} 

Esto generaría una cláusula de selección que contiene todas las columnas. Pero, si tengo una columna que contiene una gran cantidad de datos que realmente ralentiza la consulta, ¿cómo puedo hacer que mis objetos excluyan esa columna del sql generado?

Si mi mesa ha Id (int), Estado (int), datos (BLOB), ¿cómo puedo hacer que mi consulta sea

select Id, Status from TableName 

en lugar de

select Id, Status, Data from TableName 

De la sugerencia de abajo , mi método es

public IEnumerable<T> GetBy(Expression<Func<T, bool>> exp, Expression<Func<T, T>> columns) 
{ 
    return Table.Where<T>(exp).Select<T, T>(columns); 
} 

Y lo estoy llamando al igual que

mgr.GetBy(f => f.Id < 10000, n => new {n.Id, n.Status}); 

Sin embargo, estoy recibiendo un error de compilación:

Cannot implicitly convert type 'AnonymousType#1' to 'Entities.BatchRequest'

Respuesta

51

Claro. La proyección hace esto:

var q = from r in Context.TableName 
     select new 
     { 
      Id = r.Id, 
      Status = r.Status 
     } 

Aquí hay un ejemplo real (obviamente, mi base de datos tiene tablas diferentes a las suyas). Añadí mi modelo de EF para LINQPad y escribí la siguiente consulta:

from at in AddressTypes 
select new 
{ 
    Id = at.Id, 
    Code = at.Code 
} 

LINQPad me muestra que el SQL generado es:

SELECT 
    1 AS [C1], 
    [Extent1].[AddressTypeId] AS [AddressTypeId], 
    [Extent1].[Code] AS [Code] 
FROM 
    [dbo].[AddressType] AS [Extent1] 

Ninguno de los otros campos de la tabla están incluidos.

En respuesta a la pregunta actualizado

Su argumento columns dice que se necesita un tipo T y devuelve el mismo tipo. Por lo tanto, la expresión se pasa debe ser conforme a esto, o es necesario cambiar el tipo del argumento, es decir .:

public IEnumerable<U> GetBy<U>(Expression<Func<T, bool>> exp, Expression<Func<T, U>> columns) 
{ 
    return Table.Where<T>(exp).Select<T, U>(columns); 
} 

Ahora la expresión puede devolver cualquier tipo es que quiere usar.

+0

Quiero hacer esto de forma genérica para poder simplemente agregar otro argumento a la llamada al método GetBy que son las columnas que deben devolverse. – Brian

+0

Debe pasar una expresión de selección junto con su expresión where, entonces, es decir: var foo = GetBy (r => r.Id == algunaId, r => nueva {r.Id, R.Status}); –

+0

Editado mi publicación anterior con más información – Brian

Cuestiones relacionadas