Метод не может быть переведен в выражение магазина

89

Я видел, что этот код работает с 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.

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

Шон Маклин
источник

Ответы:

115

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

Решение: Следовательно, чтобы преодолеть это исключение, вам необходимо объединить свой подзапрос с основным для 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, Обходные пути для того, что не поддерживается, для подробного обсуждения возможных решений. (Обе ссылки являются кешированными версиями, потому что исходный веб-сайт не работает)

Мортеза Манави
источник