NotSupportedException: LINQ to Entities не распознает метод

Я пытаюсь заставить этот запрос работать с EF, но он выдает исключение:

var c = ac.Communities.OrderBy(o => o.Posts.Count())
        .Skip(page*limit)
        .Take(limit)
        .Select(o => o.ToViewModel()).ToArray();

Метод ToViewModel() из модели Community выглядит так:

public CommunityModel ToViewModel()
{
    return new CommunityModel()
    {
        category = Category.Name,
        created = CreationTime,
        description = Description,
        id = Id,
        name = Name,
        ownerId = Owner.Id,
        postsCount = Posts.Count(),
        score = Posts.Sum(o => o.Likes - o.Unlikes),
        shortDescription = ShortDescription,
        subscribersCount = Subscribers.Count(),
    };
}

Что я делаю неправильно?


person Reynevan    schedule 03.01.2017    source источник
comment
Чтобы исключить метод ToViewModel, поместите .ToList() перед Select и посмотрите, сохраняется ли проблема.   -  person Stuart    schedule 03.01.2017
comment
@Stuart Это работает, спасибо! Таким образом, List больше не является IQueryable, поэтому он не пытается преобразовать это в SQL-запросы для базы данных, верно? Это означает, что он делает все это в памяти, рассматривая класс Community как фактический объект, а не объект базы данных, верно?   -  person Reynevan    schedule 03.01.2017
comment
Правильно, вы форсируете перечисление IQueryable в точке использования ToList, затем следующие методы Linq действуют на коллекцию в памяти, и вам не нужно беспокоиться о переводе на SQL   -  person Stuart    schedule 03.01.2017


Ответы (2)


Entity Framework не может преобразовать методы, которые вы используете внутри ToViewModel. Используйте ToList() для быстрой загрузки результатов, а затем сопоставьте их, избегая необходимости для EF пытаться перевести SQL:

var c = ac.Communities.OrderBy(o => o.Posts.Count())
    .Skip(page*limit)
    .Take(limit)
    .ToList()
    .Select(o => o.ToViewModel()).ToArray();
person Stuart    schedule 03.01.2017

Это связано с тем, что LINQ to Entities пытается преобразовать .ToViewModel в запрос SQL, который не распознается преобразователем.

Если .Take возвращает не так много результатов, лучшим решением будет преобразовать IQueryable в List, изменив его на следующее.

var c = ac.Communities.OrderBy(o => o.Posts.Count())
        .Skip(page*limit)
        .Take(limit)
        .ToArray() // This will return a Community array
        .Select(o => o.ToViewModel()) // This is a IEnumerable<CommunityModel>
        .ToArray(); // This will cast // This is a cast for Community array
person Orel Eraki    schedule 03.01.2017
comment
Да, это то, что я собираюсь использовать. Спасибо. Однако просто из любопытства: accept Это связано с тем, что LINQ to Entities пытается преобразовать .ToViewModel в запрос SQL, который не распознается преобразователем. Если .Take возвращает не так много результатов, тогда вашим лучшим решением будет преобразование IQueryable в список, изменив его на следующее.... иначе...? - person Reynevan; 03.01.2017