Pergunta

Eu estou usando VS2008 C # Express eo banco de dados Northwind em um aplicativo do Windows Form.

Eu costumava arrastar e soltar para configurar os detalhes mestre de ligação (eu usei os Pedidos e Detalhes do pedido) para os dois DataGridViews. Neste ponto, tudo funciona como esperado. Então, para não retornar todas as linhas na tabela, eu quero filtrar a tabela Pedidos com base em um filtro para as ordens de mesa e também em um campo em ordens Detalhes tabela de. No Assistente de configuração TableAdapter, eu usei o construtor de consulta para adicionar um novo FillByMyFilter que criou a consulta a seguir:

SELECT Orders. [ID do pedido], ordens. [ID Cliente], ordens. [Employee ID], ordens. [Nome do navio], ordens. [Endereço do navio], ordens. [Navio City], ordens. [Navio Região], Ordens. [Navio Código Postal], ordens. [Navio País], ordens. [Navio Via], ordens. [Ordem Data], ordens. [Obrigatório Data], ordens. [Data de envio], Orders.Freight FROM Orders INNER JOIN [Detalhes do pedido] Pedidos on. [Order ID] = [detalhes do pedido]. [ID do pedido] WHERE (Orders. [Nome do navio] COMO N'A%) e ([detalhes do pedido] _quantidade <20)

Eu tenho isso adicionando ambas as tabelas, mas não se verificar qualquer uma das caixas de campo na tabela Detalhes do pedido para que ele só voltaria as colunas que foram usadas na consulta preenchimento original. Eu só estou tentando filtrar o DataSet na tabela de mestre neste momento e não retornar um número diferente de colunas. filho linhas de detalhes do pedido ainda deve funcionar como o padrão conjunto de resultados não filtrada.

Agora o problema: Quando eu clicar no botão Executar consulta funciona bem. Eu recebo 53 linhas da consulta acima em vez do 1078 usando o preenchimento padrão criado pelo designer. Ele retornar as mesmas colunas como a consulta preenchimento original. No entanto, quando tento executar o aplicativo eu recebo o seguinte erro de restrição:

"Falha ao ativar restrições. Uma ou mais linhas contêm valores que violem não nulo, original, ou restrições de chave estrangeira."

O que estou fazendo de errado?

UPDATE: Eu acho que eu estou recebendo o erro de restrição por causa da INNER JOIN criado pelo Assistente. Se eu editar a consulta para usar LEFT JOIN, em seguida, o Assistente muda de volta para INNER JOIN.

A minha pergunta ainda permanece como como filtrar registros na tabela pai (ordens) com base em critérios, tanto do pai e tabela filho. Meu próximo teste é tentar usar uma proc armazenado, mas gostaria de saber usando apenas o método FillBy costume TableAdapter.

Saudações,

Debug

Foi útil?

Solução 3

Obrigado a todos que postou uma resposta. Aqui está como eu fiz isso usando o Assistente de TableAdapter e do Adamastor digitado dataset.

1) Botão direito do mouse a tabela pai no designer XSD para adicionar ou configurar a consulta. 2) Clique no botão "Next" no assistente até ver o botão "Query Builder". Clique no botão Query Builder para obter-se no modo de construtor de consulta. 3) Botão direito do mouse e adicione a tabela a criança no painel de design. Você deve ter ambas as tabelas e a restrição padrão que conecta-los. 4) Clique na coluna na tabela filho que pretende filtro (esta marca de seleção será removida mais tarde), a fim de adicioná-la ao painel de critérios para que possa filtrá-la. 5) Adicione o filtro para a Controladora e colunas para crianças. Neste exemplo, eu filtrada do navio Nome LIKE 'A%' ea Ordem Quantidade <20.

Note que, neste ponto você pode testar sua consulta clicando no botão Executar consulta. Usando o Adamastor DB para SQL Server 2008 edição compacta eu recebo 53 linhas retornadas. Se você fosse para salvá-lo neste momento seria falhar em tempo de execução por causa das chaves primárias duplicados no conjunto de resultados. Assim, os próximos passos vai se livrar deles.

6) No painel de critérios, desmarque a coluna da tabela filho que você adicionou anteriormente. O filtro irá permanecer e na mesma coluna será agora desmarque no painel de design também. Se você executar a consulta, você ainda terá 53 linhas, mas sem a coluna da tabela filho. 7) Botão direito do mouse painel de estrutura e adicione o "Group By". Neste ponto, quando você executar essa consulta, você não deve ter duplicatas na ID do pedido. Eu tenho exatamente 29 linhas retornadas. 8) Clique em OK e, em seguida, no botão "Next" até que você salve sua nova consulta FillBy. 9) Alterar o código fonte para usar seu novo FillBy.

Quando eu corri a aplicação, eu tenho a tabela pai filtrada com os mesmos 29 linhas que o botão Executar consulta retornado. A tabela filho funcionou como esperado e continha pelo menos uma linha infantil que continha uma quantidade de <20.

Para uma aplicação no mundo real, eu acho que seria melhor usar uma proc armazenado ou LINQ. Mas este problema tinha-me coçar a cabeça e então eu "tornou encaixar" apenas porque era um desafio (pelo menos para mim).

Outras dicas

Este artigo contém algumas sugestões de resolução de problemas para identificar a linha exata causando o problema:

DataSet inferno - "Falha ao ativar restrições Um ou mais linhas contêm valores ...."

Se você olhar nos Orders.Designer.cs (adivinhação, como eu estou trabalhando no VB), você provavelmente vai ver uma restrição exclusiva definida sobre as encomendas (para a chave primária).

Eu suspeito que o problema é que, quando você executar a sua consulta, você está recebendo um ou Order mais individual que tem> 1 OrderDetails.Quanity> 20 .... assim, essa Ordem será devolvido duas vezes em seu conjunto de resultados, violando a chave primária.

Tente: * SELECT de encomendas onde% [Navio Name] LIKE' qualquer que seja% E OrderID em (selecione CódigoDaEncomenda da OrderDetails onde Quantidade <20)

Esta é provavelmente uma maneira muito ineficiente para fazê-lo, no Oracle você usaria existe () em vez de IN (), mas eu não sei o equivalente sql server.

Hope você tem esta respondeu, mas se não, dar a este um pensamento.

Em seu conjunto de dados se as tabelas de dados Ordem e OrderDetail ter um relacionamento entre eles, em seguida, ele funciona um pouco como uma restrição FK. Assim, não pode haver nenhum registro na tabela filho (OrderDetail) que não têm um registro cooresponding pai (Ordem). Então, o que pode estar acontecendo é quando você atualizar a Ordem DataTable, com a consulta que você menciona acima, ainda existem linhas criança na tabela OrderDetail que terá refrernces para Parent registros (ordem) que não vai estar lá após a atualização. Dito isto, se você atualizar a Ordem DataTable é preciso também atualizar a tabela de dados OrderDetail, ou remover a relação entre as duas tabelas de dados.

Espero que isso ajude ...

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