Fluente NHibernate muitos-para-muitos
-
01-07-2019 - |
Pergunta
Eu estou usando Fluent NHibernate e tendo alguns problemas recebendo muitos para muitos configuração relacionamento com uma de minhas aulas. É provavelmente um erro estúpido, mas eu estive preso por um pouco a tentar fazê-lo funcionar. De qualquer forma, eu tenho algumas classes que têm muitos-muitos relacionamentos.
public class Person
{
public Person()
{
GroupsOwned = new List<Groups>();
}
public virtual IList<Groups> GroupsOwned { get; set; }
}
public class Groups
{
public Groups()
{
Admins= new List<Person>();
}
public virtual IList<Person> Admins{ get; set; }
}
Com o mapeamento com essa aparência
Pessoa: ...
HasManyToMany<Groups>(x => x.GroupsOwned)
.WithTableName("GroupAdministrators")
.WithParentKeyColumn("PersonID")
.WithChildKeyColumn("GroupID")
.Cascade.SaveUpdate();
Grupos: ...
HasManyToMany<Person>(x => x.Admins)
.WithTableName("GroupAdministrators")
.WithParentKeyColumn("GroupID")
.WithChildKeyColumn("PersonID")
.Cascade.SaveUpdate();
Quando eu executar o meu teste de integração, basicamente, eu estou criando uma nova pessoa e grupo. Adicionando o grupo para o Person.GroupsOwned. Se eu pegar o objeto de volta Pessoa a partir do repositório, o GroupsOwned é igual ao grupo inicial, no entanto, quando eu chegar a parte de trás do grupo, se eu verificar a contagem em Group.Admins, a contagem é 0. A tabela Junte tem a GroupID eo PersonID salvo nele.
Obrigado por qualquer conselho que você pode ter.
Solução
O fato de que ele está adicionando dois registros para a aparência da tabela como você está faltando um inverso atributo . Uma vez que tanto a pessoa e o grupo estão a ser alteradas, NHibernate persiste a relação duas vezes (uma vez para cada objecto). O atributo inversa é especificamente para evitar isto.
Eu não tenho certeza sobre como adicioná-lo no mapeamento no código, mas o link mostra como fazê-lo em XML.
Outras dicas
@Santiago Eu acho que você está certo.
A resposta pode ser apenas o que você precisa para remover um de seus declarações ManyToMany, olhando mais à Fluent parece que ele poderia ser inteligente o suficiente para fazê-lo apenas para você.
Você está certificando-se de adicionar a pessoa à Groups.Admin? Você tem que fazer as duas ligações.
Você tem três mesas à direita?
Pessoas, Grupos e GroupAdministrators
quando você adicionar a ambos os lados que você começa
Pessoas (com um ID de p1) Grupos (com um id de g1)
e em GroupAdministrators você tem duas colunas e uma tabela que tem
(p1, g1)
(p1, g1)
e o teste de unidade olhares código como o seguinte.
Context hibContext //Built here
Transaction hibTrans //build and start the transaction.
Person p1 = new Person()
Groups g1 = new Groups()
p1.getGroupsOwned().add(g1)
g1.getAdmins().add(p1)
hibTrans.commit();
hibContext.close();
E, em seguida, em seu teste de fazer um novo contexto, e teste para ver o que está no contexto, e você recebe de volta a coisa certa, mas suas mesas estão todos estrumado?