Pergunta

Eu estou trabalhando em um projeto que tem um modelo de objeto rico com vários conjuntos de raízes agregadas.

Estamos usando o Castle pilha (Monorail até nHibernate com ActiveRecord).

Temos marcado as raízes agregado como [ActiveRecord(Lazy = true)] preguiçoso e ter personalizado rotinas 'ansiosos' em nosso repositório para ansioso buscar um gráfico de objeto. Usamos HQL para definir buscas ansiosas de nossa coleção filho da nossa raiz,

por exemplo. se Account é a raiz agregada (e marcado preguiçoso carregado) vamos ansioso buscar entidades Account .. Order .. Product para um grafo completo.

Portanto, não surpreende até agora (espero).

Agora, se no exemplo acima, o Produto também é marcada [ActiveRecord(Lazy = true)], este parece parar o ansioso directiva buscar no HQL.

Alguém sabe uma maneira de forçar a busca ansiosa de um objeto filho carregado preguiçoso ??

Felicidades ian

Atualizar :

Ok aqui vai um exemplo hql, usando o exemplo de 'me.yahoo.com/../1' abaixo, estamos usando IMuliQuery para reslove N + 1 dependências ao buscar ao longo de muitos para muitos relacionamentos. Também estamos usando explicitamente muitos-para-muitos classes de mapeamento. Como resultado o nosso hql é:

from Account a 'm eager loading the graph
inner join fetch a.AccountsOrders ao 
inner join fetch ao.Order
from Account a 'm eager loading the graph
inner join fetch a.AccountAddresses aa
inner join fetch aa.Address ad
where a.ID = ?

... então este executa a 2 instruções SQL e retorna o conjunto de linhas mínimo necessário, e podemos resolver esse baixo em um único gráfico de objeto. Nice.

Mas ... se, digamos, Address foi marcado preguiçoso carregado (e Order não era), acessando Order não aciona mais instruções SQL, ainda aceder Address faz, apesar do fato de ambos estão ansiosos carregado.

Então, por que não é o Address preguiçoso carregado entidade, acima, ansioso buscada pela declaração acima?

Foi útil?

Solução

Por que você quer o comportamento ansioso?

Todo o relacionamento atributos no ActiveRecord ter um '= preguiçoso' parâmetro para contar ActiveRecord para carga lenta o objeto relacionado. Todos, exceto Pertence. Pertence a verifica se o objeto dependente tem preguiçoso = true no seu atributo ActiveRecord e, em seguida, cria um proxy para o objeto em vez de fazer um seleto ou juntar-se.

Para preguiçoso de carga para trabalhar todos os métodos e propriedades da necessidade instância de classe a ser marcado como virtual. Isso permite que ActiveRecord para construir uma classe proxy dinâmico.

Agora que pode soar como uma boa idéia para buscar o gráfico completo para o desempenho, mas na prática é provavelmente mais lento. Eu tenho 3 boas razões:

1.) Pertence tem uma opção Fetch para definir como os objetos relacionados são puxados. forças FetchEnum.Join AR usar uma associação. FetchEnum. Seleccione forças AR usar instruções SELECT separadas para cada objeto. Junta são lentos, vemos uma melhoria 10x desempenho de mudar para indivíduo seleciona. Não há diferença efetiva no código do cliente entre preguiçoso = true + FetchEnum.Select e ansioso.

2.) NHibernate faz cache. Se o objeto já está em cache na sessão ou no cache de nível 2 pode ser formulário carregado lá e evitar o trabalho extra.

3.) Você iria perder todos os benefícios de carregamento lento nos casos em que você não fazer referência parte do gráfico de objeto. Mais uma vez você faria mais trabalho do que o necessário.

Outras dicas

Do uma "junção interna buscar" na entidade Account.Order.Product. Então, ao invés de algo como isso (que é o que você provavelmente já tem):

"from Account a inner join fetch a.Order where a.ID = ?"

Diga-lhe para buscar o Order.Product assim:

"from Account a inner join fetch a.Order inner join fetch a.Order.Product where a.ID = ?"

De "NHibernate em Ação", página 225:

NHibernate atualmente limita a buscar apenas uma coleção ansiosamente.

Isso pode explicar a segunda consulta para buscar os endereços.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top