2009-04-11 60 views
1

我执行标记在一个特定的实体,SQL Server 2008的我现在已经是,简化,这样的结构在使用NHibernate:获取SQL Server上使用HQL标签和标签数2008

public class Entity { 
    public Guid Id { get; set; } 
} 

public class Tag { 
    public Guid Id { get; set; } 
    public string Name { get; set; } 
} 

public class TagAssoc { 
    public Tag LinkedTag { get; set; } 
    public Entity LinkedEntity { get; set; } 
    //User 
    //Other properties 
} 

没有什么奇特的东西:一个实体可以使用相同的标签多次标记,因为该关联还包括标记实体和其他内容的用户数据。

现在,我正在尝试获取特定实体的标签列表,以及标签已应用了多少次的计数。事情是这样的HQL:

select tass.LinkedTag, count(tass.LinkedTag) 
from TagAssoc as tass left outer join tass.LinkedTag as t 
group by tass.LinkedTag 

这将生成以下SQL查询:

select tag1_.Id as Id0_, tag1_.Name as Name0_, tag1_.Id as x0_0_, count_big(tag1_.Id) as x1_0_ 
from BandTags tagassoc0_ left outer join Tags tag1_ on tagassoc0_.TagId=tag1_.Id 
group by tag1_.Id 

这看起来是正确的,但不会在SQL Server 2008中工作,因为不包括标签的名称属性在“group by”子句中。为了使它工作,我必须手动by子句为了调整该集团包括标签类的所有属性:

select tass.LinkedTag, count(tass.LinkedTag) 
from TagAssoc as tass left outer join tass.LinkedTag as t 
group by tass.LinkedTag.Id, tass.LinkedTag.Name 

但这取决于标签类的属性,因此必须更新一次课堂改变的时间。 有没有其他方法可以使第一个HQL查询工作?也许一些自动使“group by”属性显式的HQL语法?

感谢

回答

1

它不会出现,有什么办法,使NHibernate的自动确定由属性的组。该文件甚至似乎是他们给了聚合函数的例子HQL暗示这一点:

选择猫,通过cat.Id数从Eg.Cat猫组(元素(cat.Kittens)) ,猫。重量,...

在那里,他们还明确指定猫的属性。

如果您想在每次类更改时动态构建一个不需要更新的查询,我认为您遇到了Reflection和Criteria接口。

ProjectionList list = Projections.ProjectionList(); 
foreach (PropertyInfo prop in typeof(Tag).GetProperties()) 
{ 
    list.Add(Projections.GroupProperty(prop.Name)); 
} 
list.Add(Projections.Property("LinkedTag")); 
list.Add(Projections.Count("LinkedTag")); 

session.CreateCriteria(typeof(TagAssoc)).SetProjection(list).List(); 

我没有试过这个,所以它可能会或可能不会工作,或者可能需要一些调整,但你明白了。你可能会认为Tag类不会变得足够值钱。

+0

我没有想过通过反射来完成它。但现在我想我会坚持手动声明每个属性。 感谢您的回答。 :) – LorenzCK 2009-04-22 12:08:42