Trabalhar com relacionamentos muitos para muitos

Concluído

Os relacionamentos muitos para muitos fornecem a flexibilidade de controlar quando várias linhas têm os mesmos dados relacionados. Diferentemente dos relacionamentos um para muitos, os relacionamentos muitos para muitos não têm um conceito de tabela principal. O relacionamento é totalmente simétrico, e você pode acessar o conjunto de linhas relacionadas, começando de qualquer lado do relacionamento muitos para muitos. Para continuar com o modelo de dados de compartilhamento de espaço de trabalho da Contoso, as seções a seguir exploram como trabalhar com relacionamentos muitos para muitos em um aplicativo de tela usando os itens Mesa e Recurso de mesa. O diagrama a seguir ilustra o relacionamento e os dados correspondentes.

Cada mesa pode ter várias linhas de recursos de mesa associados, e você pode associar cada recurso de mesa a várias mesas. Você pode acessar o conjunto de recursos de mesa de uma linha de mesa usando a expressão ThisItem.'Desk Features'. Na linha de recursos de mesa, você pode usar a expressão ThisItem.Desks para acessar todas as mesas associadas a esse recurso de mesa específico.

Você pode usar essa expressão para mostrar uma lista de valores separados por vírgulas para cada mesa em uma galeria, conforme mostrado no exemplo a seguir.

Para realizar a tarefa de preencher o texto do rótulo, defina a propriedade Text no rótulo como a seguinte fórmula:

Concat(ThisItem.'Desk Features',Name ,",")

Esteja ciente das implicações de desempenho ao usar essa fórmula, especialmente se você tiver muitos registros, devido à forma como os dados são acessados do Dataverse. A imagem a seguir mostra que, no monitor, uma chamada para getRows é concluída para obter a lista de mesas. Para cada mesa, é feita uma chamada a getNavigatedRowInTableRow para recuperar os recursos de mesa.

Alternativamente, você pode considerar mais benéfico mostrar os recursos da mesa apenas depois que o usuário selecionar uma única linha de mesa em uma galeria ou depois de fazer o detalhamento da linha de mesa.

Outra maneira de usar o relacionamento é permitir que um usuário selecione um recurso de mesa e, em seguida, usar a propriedade controlName.Selected.Desks para preencher itens em uma galeria.

Essa abordagem funciona bem quando você só permite uma única seleção na caixa de combinação. Se você habilitar várias seleções, a lógica se tornará mais complexa. No momento, o Power Fx não tem uma forma simples de expressar uma interseção de duas coleções, necessária para fazer o cenário funcionar. Soluções alternativas são possíveis; por exemplo, você pode iterar por todos os recursos selecionados, coletar mesas relacionadas em uma única coleção, remover as duplicatas e, em seguida, usar a coleção como origem do item. No entanto, devido às várias solicitações do Dataverse (uma para cada recurso selecionado), o desempenho dessa abordagem será rapidamente reduzido à medida que as tabelas crescerem.

Estabelecer o relacionamento

A principal maneira de estabelecer um relacionamento muitos para muitos é usar a função Relate(), semelhante ao que você faria com um relacionamento um para muitos. A principal diferença é que não importa qual registro é o primeiro ou segundo parâmetro para Relate() porque nenhuma tabela principal está no relacionamento.

O gerenciamento de relacionamentos muitos para muitos em um formulário é mais complexo do que colunas de pesquisa muitos para um. O relacionamento muitos para muitos está disponível na lista de campos; entretanto, ao adicionar o campo ao formulário, o sistema não gera as fórmulas para o controle funcionar, e você receberá um erro semelhante ao exemplo a seguir.

Para resolver o problema, atualize a função Choices() na propriedade Items para a tabela que está no outro lado do relacionamento muitos para muitos. Para realizar essa tarefa, desbloqueie o cartão na guia Avançado.

No exemplo da Contoso, você deseja usar os recursos de mesa. Depois de desbloquear o controle, verifique se a propriedade Items mostra 'Recursos de Mesa' como a fonte de dados.

Observação

O cenário anterior usa o formulário para adicionar uma linha. Para dar suporte aos recursos de edição, altere a propriedade DisplayMode do cartão da configuração de Exibição padrão para Editar.

Depois que você ajustar as propriedades, a interface do usuário do formulário funcionará, e você poderá escolher os itens da caixa de combinação. No entanto, se tentar enviar o formulário, você receberá um erro semelhante ao exemplo a seguir.

Para contornar o problema, desmarque a propriedade Atualizar e processe manualmente a associação muitos para muitos depois que o formulário for enviado.

Depois que você desmarcar a propriedade Atualizar, o envio do formulário funcionará. No entanto, os relacionamentos entre as linhas da tabela Mesa e Recurso de Mesa não serão criados. Para estabelecer os relacionamentos, adicione a seguinte lógica à propriedade OnSelect do ícone de verificação usado para enviar o formulário por padrão:

  1. Salve os recursos de mesa selecionados na caixa de combinação como uma coleção. Essa etapa é necessária porque o envio do formulário redefinirá os campos, e o valor será perdido.

  2. Envie o formulário.

  3. Use a coleção de recursos de mesa salvos para estabelecer o relacionamento.

Outras opções de design

A experiência do usuário com relacionamentos muitos para muitos é semelhante às experiências em que a coluna Opções é usada. Os valores das opções são predeterminados pelo criador e não podem ser desabilitados nem protegidos. Por esse motivo, os campos de Opções são adequados para cenários com dados raramente modificados, como uma lista de países/regiões. Além disso, as linhas nas tabelas relacionadas podem ser desativadas, protegidas e adicionadas em tempo de execução. Essa capacidade torna um relacionamento muitos para muitos uma boa opção em cenários em que alguma flexibilidade é necessária no tempo de execução, como quando você está marcando uma solução em que o contato tem um relacionamento muitos para muitos com uma marca e as marcas precisam ser adicionadas pelos usuários.

Relacionamentos muitos para muitos são benéficos para situações em que você deseja capturar a associação entre linhas de duas tabelas. O relacionamento entre as linhas não pode armazenar outros dados. Por exemplo, se você tiver um relacionamento entre uma tabela de Contatos e uma de Idioma, poderá rastrear se uma pessoa fala dois idiomas.

No entanto, você não saberia há quanto tempo a pessoa fala cada idioma e qual é a proficiência dela ao falar cada um.

Um padrão de design alternativo comum é criar sua própria tabela de interseção. A tabela de Idiomas Falados a seguir é outra tabela personalizada do Dataverse. Você pode adicionar colunas a essa tabela para qualquer outra propriedade que descreva o relacionamento específico. Essa nova tabela terá relacionamentos N:1 para Contato e Idioma.

Trabalhar com essas tabelas de seu aplicativo é semelhante a trabalhar com quaisquer outras tabelas que tenham relacionamentos um para muitos ou muitos para um. Como uma tabela extra está envolvida, você poderá descobrir que lógica extra será necessária para garantir uma experiência de usuário sem problemas. É importante entender os requisitos de seu aplicativo e saber se um relacionamento muitos para muitos precisa rastrear outros dados, especialmente considerando que você precisa tomar essa decisão no momento em que as tabelas são relacionadas.