Linq to NHibernate - заказ анонимного типа - PullRequest
3 голосов
/ 30 ноября 2010

Я использую Nhibernate v2.1.2.4000. С отношениями «многие ко многим» между сообщениями и тегами у меня есть запрос:

tags
.Select(t => new { Name = t.Name, Count = t.Posts.Count })
.OrderBy(x => x.Count);

Не удается упорядочить анонимный тип (не указана ссылка на экземпляр объекта). Эта проблема связана с LinqToNH? Что может быть источником этой ошибки? Каково решение? Если это что-то связанное с LinqToNH, то как это можно решить с помощью какого-то другого варианта (например, Criteria API)?

РЕДАКТИРОВАТЬ: Когда я пробую опцию Адама ICriteria, SqlProfiler говорит, что выполненный скрипт:

SELECT this_.Name as y0_, count(this_.Id) as y1_ FROM Tag this_ GROUP BY this_.Name ORDER BY count(this_.Id) asc

Отображение для тега:

public class TagMap : ClassMap<Tag>
{
    public TagMap()
    {
        Table("Tag");
        Id(x => x.Id).GeneratedBy.GuidComb();
        Map(x => x.Name);
        HasManyToMany(x => x.Posts)
            .Table("PostTags")
            .ChildKeyColumn("Post")
            .ParentKeyColumn("Tag")
            .Cascade.None().Inverse();
    }
}

Ответы [ 2 ]

2 голосов
/ 01 декабря 2010

В NHibernate есть много вещей, которые можно использовать в NHibernate 2.1.2.4000, но они просто не будут работать.Вместо этого вы могли бы использовать HQL или ICriteria, или обновить до NHibernate 3.0, или, если вы собираетесь использовать все данные, принудительно выполнить запрос Linq после Select, добавив ToList.

tags
    .Select(t = new { t.Name, t.Posts.Count })
    .ToList()
    .OrderBy(x => x.Count);

Сам по себе анонимный объект - это то, что NHibernate.Linq может определенно обработать.

Кстати, вам не нужно указывать имя поля в анонимном объекте, если оно совпадает с полем /свойство, из которого вы его перетаскиваете.

РЕДАКТИРОВАТЬ: версия этого запроса ICriteria будет выглядеть следующим образом ...

var tags = session.CreateCriteria(typeof(Tag), "tag")
    .SetProjection(
        Projections.GroupProperty("tag.Name"),
        Projections.Count("tag.Posts"))
    .AddOrder(Order.Asc(Projections.Count("tag.Posts")))
    .List();

РЕДАКТИРОВАТЬ: при правильном отображении я получаю то жеSQL, Arch.Мое раннее отображение было неверным.Однако, похоже, что этот работает.

var tags = session.CreateCriteria(typeof(Tag), "tag")
    .CreateCriteria("tag.Posts", "post")
    .SetProjection(
        Projections.GroupProperty("tag.Name"),
        Projections.Count("post.Id"))
    .AddOrder(Order.Asc(Projections.Count("post.Id")))
    .List();

SQL, который я получаю, это ...

SELECT this_.Name as y0_, count(post1_.Id) as y1_ FROM Tag this_ inner join Post_Tags posts3_ on this_.Id=posts3_.Tag inner join Post post1_ on posts3_.Post=post1_.Id GROUP BY this_.Name ORDER BY count(post1_.Id) asc
1 голос
/ 01 декабря 2010

Попробуйте сначала заказать, а затем выбрать.У меня очень похожие запросы на 2.1.2.4, которые отлично работают.

Редактировать: Также попробуйте переключиться между Count и Count()

...