4

私は最近NHibernateを使い始めましたが、さらに下に概説したドメインモデルの実装に問題があります。

私が探しているのは、特定のデータストア上のアイテムとそのアイテムデータコレクションの間の関係をフィルタリングする方法です。データストアはグローバルであり、その場合は常に返されるか、(アプリケーションインスタンスに基づいて)ユーザーIDに固有です。

SQLでは、これは単純なクエリを使用して実行できます。

SELECT * FROM Items i
INNER JOIN ItemData id ON (i.ItemId=id.ItemId)
LEFT OUTER JOIN Users u ON (id.UserId=u.UserId)
LEFT OUTER JOIN DataStore ds ON (id.DataStoreId=ds.DataStoreId)
WHERE ds.IsGlobal = 1 OR ds.UserId = @userId

データベース構造:

DataStore:
- DataStoreId (PK)
- Name
- Weight
- UserId
- IsGlobal

Item:
- ItemId (PK)
- ... (non-nullable fields)

ItemData:
- ItemDataId (PK)
- ItemId
- DataStoreId
- ... (nullable fields)

ドメインモデル:

public class ItemMap : ClassMap<Item>
{
    public ItemMap()
    {
        Id(x => x.Id, "ItemId");
        HasMany(x => x.Data)
            .KeyColumn("ItemId")
            .ApplyFilter<ItemDataFilter>(..?)
            .Cascade.AllDeleteOrphan();
    }
}

基本的な理論は、データストアごとに1つのItemData行をフェッチし、それぞれのデータストアの重みフィールドの各列を結合することです(重みで並べ替えられた最初の非null値)。

NHibernateでこれを達成できるかどうか、またどのように達成できるかについての洞察をいただければ幸いです。

4

2 に答える 2

5

他の誰かがこの情報を探している場合に備えて、私が見つけたものは次のとおりです。

1.カスタムフィルターを作成します。

public class ItemDataFilter : FilterDefinition
{
    public ItemDataFilter()
    {
        WithName("ItemDataFilter").WithCondition("Data.DataStoreId == :DataStoreId").AddParameter("DataStoreId", NHibernate.NHibernateUtil.Int32);
    }
}

2. Fluent NHibernateプロパティマッピングを変更します(.ApplyFilter <>()を使用)。

HasMany(x => x.Data)
    .KeyColumn("ItemId")
    .ApplyFilter<ItemDataFilter>()
    .Cascade.AllDeleteOrphan();

3.リポジトリでフィルターを有効にし、現在のセッションのプロパティを設定します。

public IList<Item> GetItemsByDataStore(int DataStoreId)
    {
    using (var session = NHibernateHelper.OpenSession())
    {
        session.EnableFilter("ItemDataFilter").SetParameter("DataStoreId", DataStoreId);
        return session.CreateCriteria(typeof(Item)).List<Item>();
    }
}

これを行う別の方法は、各アイテムのすべてのItemDataをフェッチし、このフィルタリングを行う別の非マッププロパティを追加することです。

于 2011-02-28T10:14:55.387 に答える
1

単純なクエリを使用してHQLを使用してこれを行うこともできます。HQLクエリの構文は次のとおりです。

 Session.CreateQuery(hqlQuery).List();

hqlQueryは次のようになります。

 var hqlQuery= string.Format("select i from Items as i inner join i.ItemData left join Users u left join DataStire ds where u.UserId=i.UserId and ds.DataStoreId=i.DataStoreId and (ds.IsGlobal=1 or ds.UserId='{0}')",userId);

 Session.CreateQuery(hqlQuery).List<Item>();

これがうまくいくことを願っています。

于 2011-02-27T08:10:11.017 に答える