1

次のクラス構造を検討してください...

public class ListViewControl
{
    public int SystemId {get; set;}
    public List<ControlAction> Actions {get; set;}
    public List<ControlAction> ListViewActions {get; set;}
}

public class ControlAction
{
    public string blahBlah {get; set;}
}

NHibernate を使用してListViewControl クラスを熱心にロードしたいと考えています。Fluent を使用したマッピングは次のとおりです。

public UIControlMap()
    {
        Id(x => x.SystemId);
        HasMany(x => x.Actions)
            .KeyColumn("ActionId")
            .Cascade.AllDeleteOrphan()
            .AsBag()
            .Cache.ReadWrite().IncludeAll();
        HasMany(x => x.ListViewActions)
            .KeyColumn("ListViewActionId")
            .Cascade.AllDeleteOrphan()
            .AsBag()
            .Cache.ReadWrite().IncludeAll();
    }

これが私が熱心にロードしようとしている方法です

var baseActions = DetachedCriteria.For<ListViewControl>()
            .CreateCriteria("Actions", JoinType.InnerJoin)                
            .SetFetchMode("BlahBlah", FetchMode.Eager)
            .SetResultTransformer(new DistinctRootEntityResultTransformer());

var listViewActions = DetachedCriteria.For<ListViewControl>()
            .CreateCriteria("ListViewActions", JoinType.InnerJoin)
            .SetFetchMode("BlahBlah", FetchMode.Eager)
            .SetResultTransformer(new DistinctRootEntityResultTransformer());

var listViews = DetachedCriteria.For<ListViewControl>()
            .SetFetchMode("Actions", FetchMode.Eager)
            .SetFetchMode("ListViewActions",FetchMode.Eager)
            .SetResultTransformer(new DistinctRootEntityResultTransformer());

var result = _session.CreateMultiCriteria()
                .Add("listViewActions", listViewActions)
                .Add("baseActions", baseActions)
                .Add("listViews", listViews)
                .SetResultTransformer(new DistinctRootEntityResultTransformer())
                .GetResult("listViews");

さて、私の問題は、クラスがと の両方でListViewControl正しいレコードを取得することですが、同じレコードのエントリが複数あることです。レコードの数は、テーブルに対して行われた結合の数 (この場合は 2) と同じです。ActionsListViewActionsControlAction

どうすればこれを回避できますか? SetFetchModeクエリからを削除すると、listViews望ましくないプロキシを介してアクションが遅延して読み込まれます。

エイリアスも作成してみました...

.SetFetchMode("Actions", FetchMode.Eager)
.CreateAlias("Actions","actions",JoinType.RightOuterJoin)
.SetFetchMode("ListViewActions",FetchMode.Eager)
.CreateAlias("ListViewActions", "liactions", JoinType.RightOuterJoin)

これにより、重複するエントリが削除されましたが、熱心に読み込まれませんでした

4

1 に答える 1

0

これは、コレクションを熱心にロードするための非常に非効率的な方法です。より良い方法は次のとおりです。

http://ayende.com/Blog/archive/2010/01/16/eagerly-loading-entity-associations-effectively-with-nhibernate.aspx

于 2010-05-21T18:35:13.277 に答える