2009-10-07 7 views
37

Могу ли я заставить объекты EF извлекать только определенные столбцы в выполненном sql? Если я выполняю приведенный ниже код для извлечения объектов, есть ли что-то, что я могу сделать, чтобы получить только определенные столбцы, если они захотят?Только получить конкретные столбцы

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

Это создало бы предложение select, содержащее все столбцы. Но если у меня есть столбец, содержащий большой объем данных, который действительно замедляет запрос, как я могу заставить мои объекты исключать этот столбец из сгенерированного sql?

Если моя таблица Id (INT), состояние (целое), данные (BLOB), как я могу сделать мой запрос будет

select Id, Status from TableName 

вместо

select Id, Status, Data from TableName 

С ниже предложений мой метод

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

И я звоню это как так

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

Однако я получаю ошибку компиляции:

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

ответ

51

Sure. Проекция делает это:

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

Вот пример (очевидно, что у моей БД есть разные таблицы, чем у вас). Я добавил мой EF модель в LINQPad и напечатал следующий запрос:

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

LINQPad показывает мне, что сгенерированный SQL является:

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

Ни один из других полей из таблицы не включены.

В ответ на обновленный вопрос

Ваш columns аргумент говорит, что принимает тип T и возвращает тот же тип. Таким образом, выражение вы передаете должно соответствовать этому, или вам необходимо изменить тип аргумента, т.е .:

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

Теперь выражение может возвращать любой тип вы заботитесь использовать.

+0

Я хочу сделать это в общем виде, чтобы просто добавить еще один аргумент в вызов метода GetBy, который является столбцом, который должен быть возвращен. – Brian

+0

Вам нужно передать выбранное выражение вместе с вашим выражением, то есть, например: var foo = GetBy (r => r.Id == someId, r => new {r.Id, R.Status}); –

+0

Отредактировано мое сообщение выше с дополнительной информацией – Brian