2011-01-13 2 views
1

У меня есть модель представления (см. Ниже).Как создать модель представления без сортировки коллекций в памяти

public class TopicsViewModel 
{ 
    public Topic Topic { get; set; } 
    public Reply LastReply { get; set; } 
} 

Я хочу населён IQueryable<TopicsViewModel> со значениями из моей коллекции IQueryable<Topic> и IQueryable<Reply> коллекции. Я не хочу использовать прикрепленную коллекцию сущностей (т. Е. Topic.Replies), потому что мне нужен только последний ответ для этой темы и выполняю Topic.Replies.Last() загружает всю коллекцию сущности в память, а затем захватывает последнюю в список. Я пытаюсь остаться в IQueryable, чтобы запрос выполнялся в базе данных.

Я также не хочу, чтобы пропустить через темы и запрос replyRepository.Replies, потому что цикл через IQueryable<Topic> начнет ленивую загрузку. Я бы предпочел построить одно выражение и выполнить всю работу ног в нижних слоях.

У меня есть следующие:

IQueryable<TopicsViewModel> topicsViewModel = from x in topicRepository.Topics 
               from y in replyRepository.Replies 
               where y.TopicID == x.TopicID 
               orderby y.PostedDate ascending 
               select new TopicsViewModel { Topic = x, LastReply = y }; 

Но это не работает. Любые идеи, как я могу заполнить IQueryable или IEnumerable из ThreadViewModel, чтобы он запрашивал базу данных и захватывал темы и последний ответ этой темы? Я очень стараюсь избежать захвата всех ответов, связанных с этой темой. Я хочу только получить последний ответ.

Благодарим за понимание, которое вы можете предложить.

+0

Есть ли свойство навигации между темами и ответами? –

+0

Да, это была прикрепленная сущность, о которой я говорил. Однако я не хочу получать доступ к этому навигационному свойству и запускать ленивую загрузку всей коллекции. Если бы мне нужны все элементы в этой коллекции, тогда это имело бы смысл, но поскольку мне нужен только последний элемент в этой коллекции, было бы лучше как-то остаться в IQueryable. – Chev

+0

Когда вы говорите «не работает», какая именно часть не работает? Исключение времени выполнения, ничего не возвращено, или все вернулось.? –

ответ

1

Поскольку никто не отвечает, я собираюсь использовать решение foreach. Я полагаю, что перехватывать темы, которые в конечном итоге будут ленивы загружаться, намного лучше, чем заполнять подборку ответов, чтобы я мог получить доступ к последнему объекту в коллекции.

Вот что я сделал сейчас:

   List<TopicsViewModel> topicsViewModelList = new List<TopicsViewModel>(); 
       foreach (Topic topic in topics) 
       { 
        Reply lastReply = replyRepository.GetRepliesBy_TopicID(topic.TopicID).OrderBy(x => x.PostedDate).LastOrDefault(); 

        topicsViewModelList.Add(new TopicsViewModel 
        { 
         Topic = topic, 
         LastReply = lastReply 
        }); 
       } 

Я просто загружается мой IQueryable<Topics> первый, а затем циклически окончательных результатов (таким образом, чтобы обеспечивать надлежащее подкачки данных выполняется перед зацикливание) и загрузка в последнем ответе. Похоже, что он никогда не заполняет коллекцию ответов и вместо этого берет только последний ответ для каждой темы.

+1

Вам не нужно создавать экземпляры темViewModelList? – Grubsnik

+0

Да, д'о! +1 для коррекции. – Chev

0
 from r in replies 
     group r by new { r.TopicId } into g 
     select new 
      { 
       TopicId = g.Key.TopicId, 
       LastReply = g.Max(p => p.PostedDate) 
      } 
+0

Это не имеет значения. Любые попытки запросить коллекцию сущностей свойств навигации вызовут ленивую загрузку для коллекции ENTIRE. Затем LINQ выполняет функции .First() или .Last(), которые прекрасно работают, но за кулисами вся коллекция была загружена в память, а затем мы захватили первый или последний объект в коллекции. – Chev

+0

Правда. Итак, может быть, вы единственный выбор здесь, чтобы использовать функцию .Max(). –

+0

Нашел хороший пример, который сочетает SelectMany с .Max(). http://stackoverflow.com/questions/2462261/linq-to-sql-select-targets-with-max-date –

Смежные вопросы