2

NHibernate の ICriteria API を使用して表す必要がある SQL クエリがあります。

   SELECT u.Id as Id, 
    u.Login as Login, 
    u.FirstName as FirstName, 
    u.LastName as LastName, 
    gm.UserGroupId_FK as UserGroupId,
    inner.Data1,
    inner.Data2,
    inner.Data3
    FROM dbo.User u inner join 
    dbo.GroupMember gm on u.Id = gm.UserAnchorId_FK 
    left join
    (
        SELECT
        di.UserAnchorId_FK,
        sum(di.Data1) as Data1, 
        sum(di.Data2) as Data2, 
        sum(di.Data3) as Data3
        FROM
        dbo.DailyInfo di 
        WHERE di.Date between '2009-04-01' and '2009-06-01' 
        GROUP BY di.UserAnchorId_FK
    ) inner ON inner.UserAnchorId_FK = u.Id
    WHERE gm.UserGroupId_FK = 195 

これまでの試みには、'User' および 'DailyInfo' クラス (私のエンティティ) のマッピングと、DailyInfo オブジェクトを User オブジェクトのプロパティにすることが含まれていました。ただし、それらの間の外部キー関係をどのようにマッピングするかはまだ謎です。

<one-to-one></one-to-one>

<one-to-many></one-to-many>

<generator class="foreign"><param name="property">Id</param></generator> (!) 

Web での解決策は、通常、WHERE 句内のサブクエリを使用することですが、結合しない行に対して NULL 値が返されるようにするために、代わりにこのサブクエリで結合を残す必要があります。

外部クエリに基準を使用し、サブクエリを表すために DetachedCriteria と「結合」を形成する必要があると感じていますか?

4

2 に答える 2

1

私が遭遇した同じ問題と解決策が得られなかったので、インターセプターでハックしました

基準によって生成されたクエリ

SELECT u.Id as Id, 
u.Login as Login, 
u.FirstName as FirstName, 
u.LastName as LastName, 
gm.UserGroupId_FK as UserGroupId,
inner.Data1,
inner.Data2,
inner.Data3
FROM dbo.User u inner join 
dbo.GroupMember gm on u.Id = gm.UserAnchorId_FK 
InnerJoin inner ON inner.UserAnchorId_FK = u.Id
WHERE gm.UserGroupId_FK = 195

ここで、InnerJoin は User と 1 対 1 の関係を持つダミー テーブルです。InnerJoin の列は、内部結合サブクエリの戻り値です

User と InnerJoin の基準

DetachedCriteria forUser = DetachedCriteria.For<User>();
forUser.CreateCriteria("InnerJoin");

これで、インターセプターを作成してクエリを編集できます

public interface CustomInterceptor : IInterceptor, EmptyInterceptor
{    
 SqlString IInterceptor.OnPrepareStatement(SqlString sql)
 {
    string query = sql.ToString();
     if (query.Contains("InnerJoin "))
     {
        sql = sql.Replace("InnerJoin ", "(select [vals] form dbo.DailyInfo [where conditions])");
     }
     return sql;
 }
}

結合されたサブクエリを含む複数のテーブルからの戻り値については、NHibernate DTO を使用する必要があります。セッションは次のようになります

CustomInterceptor custonInterceptor=new CustomInterceptor(); 

sessionFactory.OpenSession(custonInterceptor);

そして、最後のクエリは、まさにあなたが取得したいもののようになります

于 2012-01-05T06:09:41.560 に答える
0

関係をマッピングする限り、User と DailyInfo の間に 1 対多の関係があるように思えます。

<!-- User mapping -->
<bag name="DailyInfos" inverse="true">
    <key column="UserAnchorId_FK" />
    <one-to-many class="Namespace.To.DailyInfo, Namespace" />
</bag>

<!-- DailyInfo mapping -->
<many-to-one name="User" column="UserAnchorId_FK" />

残りについては、現時点では完全にはわかりません...テーブル間UserおよびテーブルをGroup介して多対多GroupMemberになっている可能性があり、これが複雑な要因になる可能性があります。.CreateCriteria("Association path", jointype)指定した結合タイプでサブ基準を作成するために基準を実行できることに注意してください。クラス/テーブルの関係の概要を投稿すると役立つ場合があります。

于 2009-05-14T14:30:53.517 に答える