Помогите с linq orderby по отношениям агрегатов классов - PullRequest
2 голосов
/ 15 января 2009

Я немного запутался и мне нужна помощь, пожалуйста. Возьми эти два класса

public class Comment
{
     public string Message {get; set;}
     public DateTime Created {get; set;}
}

public class Post
{
    public int PostId {get; set;}
    public string Content {get; set;}
    public IList<Comment> Comments {get; set;}
}

Я хочу написать запрос linq, который возвращает одно сообщение, но упорядочено по дате создания комментария.

Итак, я начал строить свой запрос linq следующим образом:

var query = from p in _repository.GetPosts()
                        where p.PostId == id
                        orderby p.Comments.Select(x => x.Created)
                        select p;

            return query.Single();

Но оператор orderby, похоже, не работает! Он просто возвращает мой список в порядке сортировки по умолчанию. Любые предложения о том, как я могу сделать эту работу ??? Заранее спасибо!

Ответы [ 5 ]

4 голосов
/ 15 января 2009

Упорядочено по какая дата комментария? первый? последний? Вы стараетесь:

orderby p.Comments.Max(x=>x.Created)

например.

Также - ваш Single предполагает, что вы ожидаете ровно одну строку, и в этом случае нет особого смысла сортировать ее. Вы имеете в виду First()?


Или вы имеете в виду, что хотите отсортировать Comments? В этом случае сначала получите Post;

Post post = ...

Теперь ... сортировка Comments немного сложна из-за вашего IList<T> - если вы не возражаете, что это немного неэффективно, это просто:

post.Comments = post.Comments.OrderBy(x=>x.Created).ToList();

Конечно, если Comments было List<T>, вы могли бы сделать:

post.Comments.Sort((x, y) => (x.Created.CompareTo(y.Created)));

Есть также трюки, которые вы можете сделать, чтобы создать метод расширения формы:

post.Comments.Sort(x=>x.Created);
* * +1032 т.е.
public static void Sort<TSource, TKey>(
    this List<TSource> source,
    Func<TSource, TKey> selector)
{
    var comparer = Comparer<TKey>.Default;
    source.Sort((x, y) => comparer.Compare(selector(x), selector(y)));
}
1 голос
/ 15 января 2009

Возвращается в коллекции IEnumerable, значение которой не сопоставимо:

p.Comments.Select(x => x.Created)

Попробуйте вместо этого:

p.Comments.Max(x => x.Created)

Возвращает дату последнего комментария

1 голос
/ 15 января 2009

Ваш прогноз заказа возвращает IEnumerable<DateTime> - это вряд ли будет тем, что вы хотите.

В сообщении много комментариев. Какой из них вы хотите использовать в качестве даты, для которой была создана дата заказа? Мое предположение первое:

var query = from p in _repository.GetPosts()
                    where p.PostId == id
                    orderby {
                        Comment comment = p.Comments.FirstOrDefault();
                        return comment == null ? DateTime.MinValue : comment.Created;
                    }
                    select p;
0 голосов
/ 15 января 2009

Проблема в том, что вы пытаетесь отсортировать список сообщений по списку дат создания комментариев, а не сортировать список комментариев.

Если я правильно прочитал ваш вопрос, я предполагаю, что вы хотите вывести единственную запись, а затем закажите комментарии в этой записи. Попробуйте сделать следующее:

var query = from p in _repository.GetPosts()
            where p.PostId == id
            orderby p.Comments.Select(x => x.Created)
            select p;

var ret = query.Single();
ret.Comments = ret.Comments.OrderBy(x => x.Created).ToList();
return ret;
0 голосов
/ 15 января 2009

Если вы хотите отсортировать итоговый список комментариев, вы можете сделать это после извлечения сообщения, выполнив:

p.Comments = p.Comments.OrderBy(x => x.Created).ToList();

.

...