2010-11-30 3 views
3

Я использую Nhibernate v2.1.2.4000. Со многими-ко-многим между почтовыми Метки У меня есть запрос:Linq to NHibernate - закажите анонимный тип

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

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

EDIT: Когда я пытаюсь вариант Адама 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 

Mapping для Tag:

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

Есть много вещей в NHibernate.Linq для 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 может определенно обработать.

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

EDIT: версия 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(); 

EDIT: При правильном отображении я получаю один и тот же 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 
+0

спасибо за ответ. обновление до 3.0, к сожалению, сейчас не является вариантом. как это может быть написано с помощью API критериев? также я отредактировал вопрос для параметра API критериев. – rovsen 2010-12-01 21:02:44

+0

Адам, когда я пробую эту версию ICriteria в наборе результатов, всегда 1, хотя не все они равны 1. У вас есть идея, почему это происходит? – rovsen 2010-12-02 21:57:53

1

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

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

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