I am using Nhibernate v2.1.2.4000. With many-to-many relationship between Posts an Tags I have the query:
tags
.Select(t => new { Name = t.Name, Count = t.Posts.Count })
.OrderBy(x => x.Count);
Ordering anonymous type fails (reference not set to an instance of an object). Is this issue something related to LinqToNH? What can be the source of this error? What is the solution? If it is something related to LinqToNH then ho开发者_StackOverflow社区w it can be solved with some other option (ie Criteria API)?
EDIT: When I try Adam's ICriteria option, SqlProfiler says executed script is:
SELECT this_.Name as y0_, count(this_.Id) as y1_ FROM Tag this_ GROUP BY this_.Name ORDER BY count(this_.Id) asc
Mapping for 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();
}
}
There are many things in NHibernate.Linq for NHibernate 2.1.2.4000 that just won't work. You could use HQL or ICriteria instead, or upgrade to NHibernate 3.0, or if you're going to use all the data, force your Linq query to execute after the Select
by adding a ToList
.
tags
.Select(t = new { t.Name, t.Posts.Count })
.ToList()
.OrderBy(x => x.Count);
The anonymous object by itself is something that NHibernate.Linq can definitely handle.
By the way, you don't have to specify the field name in an anonymous object if it's the same as the field/property you're dragging it from.
EDIT: An ICriteria version of this query would look like this...
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: With a proper mapping I'm getting the same SQL, Arch. My earlier mapping was wrong. This one seems to work however.
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();
The SQL I get is this...
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
Try ordering first and then selecting. I have very similar queries on 2.1.2.4 that work perfectly.
Edit: Also try switching between Count
and Count()
精彩评论