Групповое объединение заставляет IQueryable превращаться в IEnumerable, почему? - PullRequest
7 голосов
/ 20 октября 2011

Я обращаюсь к удаленному источнику данных и обнаружил, что при групповом объединении запрос IQueryable преобразуется в IEnumerable,

вопрос: это повлияет на производительность? Я хочу разгрузить как можно большую часть запроса к базе данных и ничего не выполнять в памяти ...

var allusers = repo.All<User>().Where(x => x.IsActive);
var _eprofile = repo.All<Profile>()
    .Where(x => x.IsProfileActive)
    .Join(allusers, x => x.UserID, y => y.UserID, (x, y) => new
    {
        eProfile = x,
        profile = y
    })
    .GroupJoin(_abilities, x => x.eProfile.ID, y => y.ID, (x, y) => new QuoteDTO
    {
        UserID = x.profile.Login,
        Email = x.profile.Email,
        Tel = x.profile.Tel,
        Mobile = x.eProfile.Mobile,
        CompanyID = x.profile.CompanyID,
        Ability = y.Select(c => new AbilityDTO
    {
        Name= c.Name
    })

    });

Строка: .GroupJoin ( _abilities , x => x.eProfile.ID, y => y.ID, (x, y) => new QuoteDTO

  1. _abilities - это IQueryable, я получаю возможность пользователя, набор объектов
  2. вторая часть (x, y) - здесь y превращается в IEnumerable ...

var cLists = List<int>(); // эта коллекция заполняется из клиентского кода, скажем так // содержит 1,3,55 для аргументов ради ...

 var _abilities= repo.All<UserAbility>()
      .Where(x => x.Status == Status.Active.ToString())
      .Where(x => cLists.Contains(x.CompetencyID));

ПРИМЕЧАНИЕ: причина, по которой я использую var, заключается в том, что я могу превратиться в объект, который мне нравится, я использовал много анонимных типов до того, как объекты DTO были вставлены ...

1 Ответ

1 голос
/ 20 октября 2011

Определение IQueryable:

public interface IQueryable<T> : IEnumerable<T>, IQueryable, IEnumerable

... и ObjectQuery:

ObjectQuery<T> : ObjectQuery, IOrderedQueryable<T>, IQueryable<T>, IEnumerable<T>, IOrderedQueryable, IQueryable, IEnumerable, IListSource

Большинство (все?) Выражений LINQ возвращают объект, приведенный как IEnumerable.Но тип объекта остается тем же типом, с которого он был запущен.

Нет, база данных не подвергается ударам, когда запрос LINQ-to-Entities приведен как IEnumerable, поэтому производительность не снижается.При желании вы можете выполнить обновление до IQueryable или ObjectQuery.

Редактировать: Для пояснения, вызов ToArray () для экземпляра ObjectQuery, IQueryable или IEnumerable действительно попадает в базу данных и получает набор результатов.

Редактировать: Создание нового объекта в запросе (т. Е. Нового QuoteDTO) ударит по базе данных, поскольку нет способа сохранить новый объект в запросе SQL.Извините, я пропустил этот бит раньше.

...