Linq с подзапросом с Let

То, что я пытаюсь получить из этого запроса Linq, - это список всех объявлений, в которых самый последний связанный журнал с LogType.IsStatus == true имеет LogType.Name либо подтверждено, либо обновлено. Для ясности: у объявления много журналов, и у каждого журнала есть один тип журнала. Пока у меня есть следующее, но это дает мне ошибку System.NotSupportedException в LastOrDefault.

var adverts = (from a in database.Adverts
                      let lastLog = (from l in a.Logs
                                     where l.LogType.IsStatus == true
                                     orderby l.Created_at
                                     select l).LastOrDefault()
                      where (lastLog != null)
                            &&
                            (lastLog.LogType.Name == "Confirmed" || lastLog.LogType.Name == "Renewed")
                            orderby a.Created_at descending
                      select a).ToList();

person Jay    schedule 14.03.2011    source источник


Ответы (2)


LastOrDefault() не поддерживается в LINQ to Entities (см. здесь).

Вы можете обойти это, изменив предложение order by в подзапросе let на order by descending, а затем вместо этого используйте FirstOrDefault().

var adverts = (from a in database.Adverts
               let lastLog = (from l in a.Logs
                              where l.LogType.IsStatus == true
                              orderby l.Created_at descending
                              select l).FirstOrDefault()
               where (lastLog != null)
                     &&
                     (lastLog.LogType.Name == "Confirmed" || lastLog.LogType.Name == "Renewed")
                      orderby a.Created_at descending
               select a).ToList();
person Doctor Jones    schedule 14.03.2011
comment
Запрос, кажется, обрабатывается, но я, похоже, получаю System.NotSupportedException: указанный метод не поддерживается этим, когда я перехожу к циклическому просмотру рекламных объявлений в моем представлении: @foreach (элемент var в модели). Я упустил что-то простое? - person Jay; 14.03.2011
comment
Говорится, какой метод не поддерживается? Что это за Model коллекция, которую вы повторяете в foreach (var item in Model)? - person Doctor Jones; 14.03.2011
comment
У меня строго типизированный взгляд на рекламу. Исключением является заедание строки foreach, если я удалю часть запроса ToList (), иначе она зацепится за сам запрос. - person Jay; 14.03.2011
comment
Какой метод не поддерживается? - person Doctor Jones; 14.03.2011
comment
Немного сложно решить. Внутренний источник исключения - MySql.Data.Entity. Кажется, что-то связано с методом ToList () - stackoverflow.com/questions/1555914/ попробовал отмеченное здесь решение, но когда я пытаюсь преобразовать результаты ToList (), возникает ошибка! - person Jay; 14.03.2011
comment
Я не уверен, в чем причина, это сложно, не имея более подробной информации о вашей модели. Вопрос, на который вы указали ссылку, предполагает, что ошибка вызвана использованием настраиваемого свойства в запросе LINQ. Пользовательские свойства не поддерживаются LINQ to Entities. Вы пытаетесь использовать какие-либо здесь? - person Doctor Jones; 14.03.2011
comment
Это сработает, если я удалю предложение where внешнего запроса, т.е. если я не использую переменную lastLog, но как только я верну WHERE, возвращается NotSupportedException. Ночной кошмар! - person Jay; 14.03.2011
comment
Этот запрос работает? database.Logs.Where(l => l.LogType.Name == "Confirmed" || l.LogType.Name == "Renewed").ToList(); - person Doctor Jones; 14.03.2011
comment
Помечено как ответ, поскольку вы разобрались с моей исходной проблемой с помощью LastOrDefault (). С остальными проблемами мне удалось разобраться, изменив запрос на отредактированную версию. - person Jay; 15.03.2011
comment
Отлично, я рад, что вы разобрали :-) - person Doctor Jones; 15.03.2011

попробуй это

var lookingType = new string[]{"Confirmed", "Renewed"};

var result = database.Adverts
  .Where(entry 
    => entry.Logs.Count() > 0 && entry.Logs.Any(log => log.LogType.IsStatus))
  .Select(entry 
    => new { data = entry, 
       lastLog = entry.Logs.OrderByDescending(log => log.Created_at).First() 
    })
  .Where(entry => lookingType.Contains(entry.lastLog.LogType.Name))
  .Select(entry => entry.data).ToList();
person Bonshington    schedule 14.03.2011