Nhibernate объединить на столе в два раза - PullRequest
1 голос
/ 21 мая 2010

Рассмотрим следующую структуру класса ...

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;}
}

Я хочу загрузить класс ListViewControl с нетерпением , используя NHibernate. Отображение с использованием 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 получает правильные записи как в Actions, так и в ListViewActions, но существует несколько записей одной и той же записи. Количество записей равно количеству соединений, выполненных в таблице ControlAction, в данном случае две.

Как я могу избежать этого? Если я удаляю SetFetchMode из запроса listViews, действия загружаются через прокси-сервер, который мне не нужен.

Я также пытался создать псевдонимы ...

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

Это удалило дубликаты записей, но не загружало

1 Ответ

0 голосов
/ 21 мая 2010

Это крайне неэффективный способ загружать коллекции. Вот лучший способ:

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

...