Lista vs Set vs Bag em NHibernate

109

Qual é a diferença entre uma lista, conjunto e saco no arquivo de mapeamento NHibernate? Como cada um se relaciona com as coleções .NET?

mrblah
fonte

Respostas:

230

Semântica NHibernate:

  1. Lista: coleção ordenada de entidades, duplicatas permitidas. Use um .NET IListno código. A coluna de índice precisará ser mapeada no NHibernate.

  2. Conjunto: coleção não ordenada de entidades únicas, duplicatas não permitidas. Use Iesi.Collection.ISetem código (NH anterior a v4) ou System.Collections.Generic.ISet(NH v4 +). É importante substituir GetHashCodee Equalsindicar a definição de negócios de duplicado. Pode ser classificado definindo um pedido por ou definindo um comparador resultando em um SortedSetresultado.

  3. Saco: lista não ordenada de entidades, duplicatas permitidas. Use um .NET ICollection<T>no código. A coluna de índice da lista não é mapeada e não é respeitada pelo NHibernate.

Michael Gattuso
fonte
Re: # 2, não podemos usar apenas regular em ISetvez de Iesi?
Sergei Tachenov
@SergeyTachenov: consulte stackoverflow.com/questions/9222058/… para uma possível resposta. Quando esta resposta foi escrita, o ISet não fazia parte de .net
Michael Gattuso
A resposta menos popular para essa pergunta é sim, desde NHibernate 4. Então, talvez essa pergunta precise ser editada também.
Sergei Tachenov
21

Todos esses objetos no NHibernate são exatamente os mesmos que outras implementações desses Abstract Data Types (ADT). Fiquei surpreso com o quão difícil é encontrar Conjuntos e Bolsas online por causa de como os nomes são comuns para outras coisas, então listei alguns links e descrições aqui.

Para obter informações mais detalhadas, dê uma olhada no seguinte: Listas , Conjuntos e Bolsas

As regras gerais são:

As listas são ordenadas por padrão, use-as se quiser ser capaz de puxar um objeto por seu índice ou se tiver um gosto estranho de forloops sobre foreachloops. Você não é obrigado a acessá-los como faria em uma lista vinculada . Este ADT permite duplicatas.

Observe! Embora as listas sejam ordenadas conforme BryanD mencionou em sua resposta, não há absolutamente nada dizendo que ela deva estar na ordem que você espera do banco de dados ao executar uma consulta HQL, a menos que especifique uma ordem por comando. É por isso que algumas pessoas gostam de usar Set ou Bags, para não dar a ilusão de serem encomendados. Embora eu diga isso, na maioria das vezes eles parecerão estar em uma ordem visível, já que são adicionados à lista na ordem em que são encontrados na consulta que o NHibernate executa.

Os conjuntos não são ordenados por padrão, você não pode acessar nenhuma variável diretamente por meio de um índice. Os conjuntos são, por padrão, o único ADT dos três acima que mantêm a exclusividade de seus objetos . Eles são ótimos se você tiver uma coleção, caso precise não conter duplicatas.

Bags (ou Multisets ) são, como você pode ver nos links acima, um tipo de Set que permite que os objetos dentro dele sejam duplicatas de outros objetos. Eles geralmente não são usados, pois a ordem das Listas pode ser ignorada e, portanto, tratada como uma Bolsa.

Em relação a como eles são usados ​​no NHibernate, nada é puxado do banco de dados de forma diferente dependendo de qual ADT você seleciona aqui, é para que você deseja usá-lo que deve fazer você escolher o ADT diferente.

Pessoalmente, eu uso Sets para a maioria das coisas, pois geralmente exijo que os objetos filhos sejam exclusivos e a ordem não é um problema. Embora eu use Listas onde tenho um grupo de objetos que desejo ordenados por algo, por exemplo, tempo, para atingir essa ordem, preciso definir manualmente o "ordenar por" na consulta HQL.

Jay
fonte
2
Correção na lista - usando uma lista em um arquivo de mapeamento NHibernate WILL requer o mapeamento de uma coluna de índice. Desta forma, a lista será retirada na ordem exata em que foi colocada.
Michael Gattuso
@Michael Gattuso Bom argumento, eu deveria ter mencionado na resposta acima que estava falando sobre consultas HQL (daí o comentário 'ordenar por') em vez da especificação de coleção real em seu arquivo de mapeamento.
Jay
Um benefício de usar sacos é que eles não precisam ser carregados do banco de dados quando você adiciona novos elementos a ele. Sem duplicatas para verificar, sem ordem para determinar.
tvaananen,
1

Bem, a principal diferença é que as listas têm uma ordem implícita para os elementos, indexados por sua posição na lista. Conjuntos e bolsas também podem ser "pedidos" geralmente por um Comparador ou um pedido por cláusula que é aplicado quando esses itens saem do DB. Pessoalmente, nunca usei Bags ... se eu sei que os dados que desejo estão ordenados sequencialmente, uso List, caso contrário, uso Set.

BryanD
fonte
0

Definir não permite que você tenha elementos repetidos nele. Se você tentar adicionar algum novo elemento, ele irá comparar (método Equals é usado) cada elemento que já está na coleção com aquele que você adicionou, e se um retornar verdadeiro, o elemento não será adicionado

Astuto
fonte