1

SQL Server 2008 で NHibernate を使用して、特定のエンティティにタグ付けを実装しています。現在の構造は、単純化すると次のようになります。

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

これは正しいように見えますが、Tag の Name プロパティが "group by" 句に含まれていないため、SQL Server 2008 では機能しません。これを機能させるには、Tag クラスのすべてのプロパティを含めるために、group 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

ただし、これは Tag クラスのプロパティに依存するため、クラスが変更されるたびに更新する必要があります。最初の HQL クエリを機能させる他の方法はありますか? おそらく、「グループ化」プロパティを明示的にする HQL 構文でしょうか?

ありがとう

4

1 に答える 1

1

NHibernate に group by プロパティを自動的に決定させる方法はないようです。ドキュメンテーションは、集約関数に対して提供するHQLの例でこれを暗示しているようです:

select cat, count( elements(cat.Kittens) ) from Eg.Cat cat group by cat.Id, cat.Weight, ...

そこでは、Cat のプロパティも明示的に指定します。

クラスが変更されるたびに更新を必要としないクエリを動的に構築したい場合は、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 クラスを変更しないと判断するかもしれません。

于 2009-04-16T15:26:41.927 に答える