Atributo inverso em NHibernate

89

Como faço para usar o atributo inverso? Se não estou enganado, para um para muitos relacionamentos, o atributo inverso deve ser definido como verdadeiro. Para relacionamentos muitos para muitos, um dos atributos inversos da classe de entidade deve ser definido como verdadeiro e outro como falso.

Alguém pode lançar algumas luzes sobre isso?

Graviton
fonte
2
Você também pode verificar minha resposta, " Quando usar inverse =" true | false " ", em uma pergunta semelhante.
Daniel Schilling

Respostas:

125

O atributo inverso não deve ser definido como verdadeiro ...

Você usa o atributo inverse para especificar o 'proprietário' da associação. (Uma associação pode ter apenas um proprietário, então uma extremidade deve ser definida como inversa, a outra deve ser definida como 'não inversa'). (Proprietário inverse=false:; Não proprietário inverse=true:)

Em uma associação um-para-muitos, se você não marcar a coleção como a extremidade inversa, o NHibernate executará um UPDATE adicional. Na verdade, neste caso, o NHibernate irá primeiro inserir a entidade que está contida na coleção, se necessário inserir a entidade que possui a coleção, e depois, atualiza a 'entidade da coleção', para que a chave estrangeira seja definida e a associação é feito. (Observe que isso também significa que a chave estrangeira em seu banco de dados deve ser anulável).

Quando você marca o final da coleção como 'inverso', então o NHibernate irá primeiro persistir a entidade que 'possui' a coleção, e irá persistir as entidades que estão na coleção depois, evitando uma instrução UPDATE adicional.

Então, em uma associação bidirecional, você sempre tem uma extremidade inversa.

Frederik Gheysels
fonte
4
Isso explica tudo, apenas para adicionar proprietário é aquele que tem chave estrangeira na tabela
Brijesh Mishra
48
Na minha opinião, essa terminologia é muito ruim. Por que não marcar a propriedade ao invés do 'inverso' ?!
UpTheCreek de
1
+1 para usar negação em um termo já negado :) "O atributo INVERSE NÃO DEVE ser definido como verdadeiro"
contactmatt
Boa resposta, a única questão que resta é como decidir quem deve ser o "proprietário"
PandaWood
E quanto a muitos para muitos quando você tem uma mesa intermediária que mantém a relação entre 2 entidades?
Dark_Knight
10

Além da resposta acima , e de acordo com meu entendimento, você precisa persistir o valor da chave estrangeira na coleção manualmente, ou seja, se você não quiser a instrução de atualização extra:

Parent par = Session.Get<Parent>(8);

Child ch = new Child();
ch.Name = "Emad";

//set the parent foreign key manually
ch.MyParent = par;

par.MyChildren.Add(ch);
Session.Save(par);

para mais explicações sobre o atributo inverso, verifique a seguinte postagem:

http://www.emadashi.com/index.php/2008/08/nhibernate-inverse-attribute/

Emad Alashi
fonte
2

Eu posso ver onde o "dono" entra, mas uma associação é um cano, e você pode olhar para baixo em qualquer uma das extremidades, então o que quer dizer qual entidade "possui" o cano.

Uma maneira diferente de ver isso é que, em um relacionamento Um para Muitos, há na verdade 2 relacionamentos acontecendo.

Relacionamento 1: pai para muitos filhos.

Relação 2: cada criança com um pai

Portanto, o NH tentará executar o sql para armazenar cada um deles no banco de dados. Mas não é necessário porque quando você define a chave estrangeira, por exemplo, no relacionamento 2 quando um filho é armazenado, ele automaticamente corrige o relacionamento de um dos pais para o filho também, porque o relacionamento 1 é o "inverso" do relacionamento 2 .

Portanto, significa inverso, é algo que obtemos por padrão, uma vez que definimos o relacionamento principal. ou seja, não há necessidade de o NH executar sql para corrigir o relacionamento 1 e, ao marcar a coleção filho como um NH Inverso, a execução do sql será ignorada quando a coleção filho for adicionada.

Eu presumiria que, se você não dissesse ao NH que era o inverso, seria um desperdício de esforço fazer sql para tentar estabelecer a relação inversa também - embora não fosse necessário.

Mickey Puri
fonte