Метод не может быть переведен в выражение хранилища

Я видел, как этот код работает с LINQ to SQL, но когда я использую Entity Framework, он вызывает эту ошибку:

LINQ to Entities не распознает метод 'System.Linq.IQueryable'1 [MyProject.Models.CommunityFeatures] GetCommunityFeatures()', и этот метод не может быть переведен в выражение хранилища. `

Код репозитория:

public IQueryable<Models.Estate> GetEstates()
{
    return from e in entity.Estates
           let AllCommFeat = GetCommunityFeatures()
           let AllHomeFeat = GetHomeFeatures()
           select new Models.Estate
                      {
                                EstateId = e.EstateId,
                                AllHomeFeatures = new LazyList<HomeFeatures>(AllHomeFeat),
                                AllCommunityFeatures = new LazyList<CommunityFeatures>(AllCommFeat)
                      };
}

public IQueryable<Models.CommunityFeatures> GetCommunityFeatures()
{
    return from f in entity.CommunityFeatures
           select new CommunityFeatures
                      {
                          Name = f.CommunityFeature1,
                          CommunityFeatureId = f.CommunityFeatureId
                      };
}

public IQueryable<Models.HomeFeatures> GetHomeFeatures()
{
    return from f in entity.HomeFeatures
           select new HomeFeatures()
           {
               Name = f.HomeFeature1,
               HomeFeatureId = f.HomeFeatureId
           };
}

LazyList - это список, который расширяет возможности IQueryable.

Может ли кто-нибудь объяснить, почему возникает эта ошибка?

Ответ 1

Причина: По дизайну LINQ to Entities требуется, чтобы выражение запроса LINQ было переведено на серверный запрос. Только несколько некоррелированных подвыражений (выражения в запросе, которые не зависят от результатов от сервера) оцениваются на клиенте до того, как запрос будет переведен. Произвольные вызовы метода, которые не имеют известного перевода, такие как GetHomeFeatures() в этом случае, не поддерживаются.
Чтобы быть более конкретным, LINQ to Entities поддерживает только конструкторы Parameterless и инициализаторы.

Решение: Поэтому, чтобы преодолеть это исключение, вам нужно объединить свой дополнительный запрос в основной для GetCommunityFeatures() и GetHomeFeatures() вместо прямого вызова методов из запроса LINQ. Кроме того, существует проблема в том, что вы пытались создать экземпляр LazyList с помощью его параметризованных конструкторов, как и в LINQ to SQL. Для этого решением было бы перейти на оценку клиентов запросов LINQ (LINQ to Objects). Это потребует, чтобы вы вызывали метод AsEnumerable для ваших запросов LINQ to Entities до вызова конструктора LazyList.

Что-то вроде этого должно работать:

public IQueryable<Models.Estate> GetEstates()
{
    return from e in entity.Estates.AsEnumerable()
       let AllCommFeat = from f in entity.CommunityFeatures
                         select new CommunityFeatures {
                             Name = f.CommunityFeature1,
                             CommunityFeatureId = f.CommunityFeatureId
                         },
       let AllHomeFeat = from f in entity.HomeFeatures
                         select new HomeFeatures() {
                             Name = f.HomeFeature1,
                             HomeFeatureId = f.HomeFeatureId
                         },
       select new Models.Estate {
            EstateId = e.EstateId,
            AllHomeFeatures = new LazyList<HomeFeatures>(AllHomeFeat),
            AllCommunityFeatures = new LazyList<CommunityFeatures>(AllCommFeat)
       };
}


Дополнительная информация: Пожалуйста, посмотрите LINQ to Entities, что не поддерживается? для получения дополнительной информации. Также ознакомьтесь с LINQ to Entities, обходные решения для того, что не поддерживается, для подробного обсуждения возможных решений. (Обе ссылки - это кешированные версии, поскольку исходный веб-сайт не работает)