Linq to NHibernate - 订购匿名类型

时间:2010-11-30 20:44:08

标签: nhibernate linq-to-nhibernate

我正在使用Nhibernate v2.1.2.4000。帖子和标签之间的多对多关系我有查询:

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

订购匿名类型失败(引用未设置为对象的实例)。这个问题与LinqToNH有关吗?这个错误的根源是什么?解决办法是什么? 如果它与LinqToNH相关,那么如何通过其他选项(即Criteria API)解决它?

编辑:当我尝试使用Adam的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 个答案:

答案 0 :(得分:2)

NHibernate.Linq NHibernate 2.1.2.4000中有很多东西是行不通的。您可以使用HQL或ICriteria,或升级到NHibernate 3.0,或者如果您要使用所有数据,请通过添加Select强制您的Linq查询在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 :(得分:1)

先尝试先订购然后再选择。我对2.1.2.4上的查询非常相似,完美无缺。

修改:同时尝试在CountCount()

之间切换