Atualizar DataGridView usando Linq com C# (tabela com FK)

24/10/2009

Amigos, meu primeiro chamado.

Preciso atualizar um grid utilizando Visual Studio 2008, LINQ e C#.
Estou em um projeto Windows Forms.

Eu navego entre os campos fk, do tipo tblMaster.tblDetail.field
Mas o problema eh que quando chego no field, o campo tem o mesmo nome da tabela master, e o select não aceita campos com nomes iguais.

Eu criei um método dentro da unit, do form, mas estou passando tudo pra classes.

Uma amiga me disse que existe uma maneira muito melhor de se atualizar um grid, criando uma classe pra isso, e utilizando uma collection de objects, mas eu não entendi muito bem.

Vou passar o meu método (que está dentro do corpo do form) e gostaria que vocês consultores analizassem, mas não apenas corrigissem o erro e me possibilitem atualizar o grid com esse select dentro do form.
Gostaria que me passassem a maneira correta de se atualizar um grid com LINQ, utilizando uma classe, ou no mínimo um método de classe para isso.

Lembrando que não posso modificar as tabelas facilmente, pois elas são desenvolvidas por um DBA que nos presta consultoria, e a minha versão ficaria diferente da versão dele. So mudaria se fosse estritamente necessário)

Vou postar o meu método, e a partir dele vocês ficam a par da tabela, dos campos e das fks.
Fico a disposição pra postar trechos de código, scrip de tabela, o que for necessário!

        private void atualizarGrid()
        {
            try
            {
                //Instancia da classe de conexão com o LINQ
                Entities db = new Entities();

                //Le o ID do item do combo atraves da property Value
                int codGrupoSubFamilia = Convert.ToInt32(cmbGrupoSubFamilia.SelectedValue);
                int codGrupoSub = Convert.ToInt32(cmbGrupoSub.SelectedValue);
                int codGrupo = Convert.ToInt32(cmbGrupo.SelectedValue);

                //Le os registros com os parametros dos 3 combos e preenche o GRID
                var newProdutoFilter = (from p in db.Produto
                                        where (
                                        (p.GrupoSubFamilia.codigoGrupoSub == codGrupoSub) &&
                                        (p.GrupoSubFamilia.codigoGrupoSubFamilia == codGrupoSubFamilia) &&
                                        (p.GrupoSubFamilia.codigoGrupo == codGrupo))
                                        orderby p.codigo descending
                                        select new
                                        {
                                            p.codigo,
                                            p.descricao,
                                            p.descricaoReduzida,
                                            p.descricaoECF,
                                            undMedProd = p.UnidadeMedida.codigo,
                                            grupoCod = p.GrupoSubFamilia.GrupoSub.Grupo.codigo,
                                            p.GrupoSubFamilia.GrupoSub.codigoGrupoSub,
                                            p.GrupoSubFamilia.codigoGrupoSubFamilia,
                                            p.tipo,
                                            p.ativo
                                        });
                grdProduto.DataSource = newProdutoFilter;

                btnNovoProduto.Enabled = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show("Problema ao atualizar o grid : \n"
                                + ex.Message,
                                "Atualizar Grid"
                                );
            }
        }

Como podem ver, tive de apelidar 2 campos, pois dava erro de compilação ao utilizar nomes de campos iguais...
Como disse anteriormente eu preferia uma nova orientação a seguir, como utilizar uma classe pra preencher grid, pois em uma classe eu poderia nomear os campos como bem entendesse.

Fico no aguardo e espero que tenham entendido meu problema!
Daniel Vieira

Daniel Vieira

Curtidas 0

Respostas

Fabio Mans

Fabio Mans

24/10/2009

André tudo bem? Não entendi muito bem sua dúvida mas o que você quer é criar um método que te retorne os dados para que você preencha o Grid é isso? Você acha que está carregando o Grid através da UI, se for isso não é complicado, você pode criar um projeto Class Library com os métodos que retornem os dados ou apenas uma classe no mesmo projeto.     Este método pode ser feito como você fez na página e retornando um List por exemplo. Passe pra mim o script da sua tabela que vou simular em um projeto.   Fabio  
GOSTEI 0
Daniel Vieira

Daniel Vieira

24/10/2009

Tabela Produto

/****** Object:  Table [Materiais].[Produto]    Script Date: 10/26/2009 09:38:51 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [Materiais].[Produto](
    [codigo] [int] IDENTITY(1,1) NOT NULL,
    [descricao] [varchar](120) NOT NULL,
    [descricaoReduzida] [varchar](120) NULL,
    [descricaoECF] [varchar](50) NULL,
    [unidadeMedida] [varchar](6) NOT NULL,
    [codigoGrupo] [int] NOT NULL,
    [codigoGrupoSub] [int] NOT NULL,
    [codigoGrupoSubFamilia] [int] NOT NULL,
    [tipo] [char](1) NOT NULL,
    [ativo] [char](1) NOT NULL,
    [dataInclusao] [datetime] NOT NULL,
    [dataUltimaAtualizacaoCadastral] [datetime] NOT NULL,
    [codigoUsuario] [int] NOT NULL,
 CONSTRAINT [PK_prod] PRIMARY KEY CLUSTERED
(
    [codigo] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING ON
GO

ALTER TABLE [Materiais].[Produto]  WITH CHECK ADD  CONSTRAINT [FK_Produto_GrupoSubFamilia] FOREIGN KEY([codigoGrupo], [codigoGrupoSub], [codigoGrupoSubFamilia])
REFERENCES [Materiais].[GrupoSubFamilia] ([codigoGrupo], [codigoGrupoSub], [codigoGrupoSubFamilia])
GO

ALTER TABLE [Materiais].[Produto] CHECK CONSTRAINT [FK_Produto_GrupoSubFamilia]
GO

ALTER TABLE [Materiais].[Produto]  WITH CHECK ADD  CONSTRAINT [FK_Produto_UnidadeMedida] FOREIGN KEY([unidadeMedida])
REFERENCES [Materiais].[UnidadeMedida] ([codigo])
GO

ALTER TABLE [Materiais].[Produto] CHECK CONSTRAINT [FK_Produto_UnidadeMedida]
GO

ALTER TABLE [Materiais].[Produto]  WITH CHECK ADD  CONSTRAINT [FK_Produto_Usuario] FOREIGN KEY([codigoUsuario])
REFERENCES [dbo].[Usuario] ([codigo])
GO

ALTER TABLE [Materiais].[Produto] CHECK CONSTRAINT [FK_Produto_Usuario]
GO

----------------------------------------------------------
Tabela UnidadeMedida

USE [CONSTRUSYS]
GO

/****** Object:  Table [Materiais].[UnidadeMedida]    Script Date: 10/26/2009 09:42:39 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [Materiais].[UnidadeMedida](
    [codigo] [varchar](6) NOT NULL,
    [descricao] [varchar](50) NOT NULL,
 CONSTRAINT [PK_UnidadeMedida] PRIMARY KEY CLUSTERED
(
    [codigo] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING ON
GO

-----------------------------------------------------------------------------------------------------------------
Tabela GrupoSubFamilia

USE [CONSTRUSYS]
GO

/****** Object:  Table [Materiais].[GrupoSubFamilia]    Script Date: 10/26/2009 09:44:47 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [Materiais].[GrupoSubFamilia](
    [codigoGrupo] [int] NOT NULL,
    [codigoGrupoSub] [int] NOT NULL,
    [codigoGrupoSubFamilia] [int] NOT NULL,
    [descricao] [varchar](50) NOT NULL,
    [comissao] [decimal](4, 2) NOT NULL,
    [rentabilidade] [decimal](5, 2) NOT NULL,
    [ativo] [char](1) NOT NULL,
 CONSTRAINT [PK_GrupoSubFamilia] PRIMARY KEY NONCLUSTERED
(
    [codigoGrupo] ASC,
    [codigoGrupoSub] ASC,
    [codigoGrupoSubFamilia] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING ON
GO

ALTER TABLE [Materiais].[GrupoSubFamilia]  WITH CHECK ADD  CONSTRAINT [FK_GrupoSubFamilia_GrupoSub] FOREIGN KEY([codigoGrupo], [codigoGrupoSub])
REFERENCES [Materiais].[GrupoSub] ([codigoGrupo], [codigoGrupoSub])
GO

ALTER TABLE [Materiais].[GrupoSubFamilia] CHECK CONSTRAINT [FK_GrupoSubFamilia_GrupoSub]
GO

ALTER TABLE [Materiais].[GrupoSubFamilia] ADD  DEFAULT ('S') FOR [ativo]
GO

-------------------------------------------------------------------------------------------------------------------------

Vou postar uma ScreenShot do meu MER, pra voce ter uma ideia geral dos relacionamentos:



Se precisar de algum outro script é só dizer.

Mas sobre o chamado, o que você disse é o que eu realmente quero, uma classe com os métodos que retornem uma lista, e a partir dessa lista eu preencha meu grid.







GOSTEI 0
Fabio Mans

Fabio Mans

24/10/2009

Faltou Grupo e GrupoSub
GOSTEI 0
Daniel Vieira

Daniel Vieira

24/10/2009

Tabela Grupo

USE [CONSTRUSYS]
GO

/****** Object:  Table [Materiais].[Grupo]    Script Date: 10/26/2009 11:18:07 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [Materiais].[Grupo](
    [codigo] [int] IDENTITY(1,1) NOT NULL,
    [descricao] [varchar](50) NOT NULL,
    [comissao] [decimal](4, 2) NOT NULL,
    [rentabilidade] [decimal](5, 2) NOT NULL,
    [ativo] [char](1) NOT NULL,
    [codigoUsuario] [int] NULL,
 CONSTRAINT [PK_Grupo] PRIMARY KEY NONCLUSTERED
(
    [codigo] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY],
UNIQUE NONCLUSTERED
(
    [descricao] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY],
UNIQUE NONCLUSTERED
(
    [descricao] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING ON
GO

ALTER TABLE [Materiais].[Grupo] ADD  DEFAULT ('S') FOR [ativo]
GO

---------------------------------------------------------------------------------

Tabela GrupoSub

USE [CONSTRUSYS]
GO

/****** Object:  Table [Materiais].[GrupoSub]    Script Date: 10/26/2009 11:19:28 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [Materiais].[GrupoSub](
    [codigoGrupo] [int] NOT NULL,
    [codigoGrupoSub] [int] NOT NULL,
    [descricao] [varchar](50) NOT NULL,
    [comissao] [decimal](4, 2) NOT NULL,
    [rentabilidade] [decimal](5, 2) NOT NULL,
    [ativo] [char](1) NOT NULL,
 CONSTRAINT [PK_GrupoSub] PRIMARY KEY NONCLUSTERED
(
    [codigoGrupo] ASC,
    [codigoGrupoSub] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING ON
GO

ALTER TABLE [Materiais].[GrupoSub]  WITH CHECK ADD  CONSTRAINT [FK_GrupoSub_Grupo] FOREIGN KEY([codigoGrupo])
REFERENCES [Materiais].[Grupo] ([codigo])
GO

ALTER TABLE [Materiais].[GrupoSub] CHECK CONSTRAINT [FK_GrupoSub_Grupo]
GO

ALTER TABLE [Materiais].[GrupoSub] ADD  DEFAULT ('S') FOR [ativo]
GO



GOSTEI 0
Fabio Mans

Fabio Mans

24/10/2009

Você está utilizando Linq to SQL ou Entity Framework?
GOSTEI 0
Daniel Vieira

Daniel Vieira

24/10/2009

Fabio, creio eu que estou utilizando Entity Framework!

Como assim creio eu??

Eu estou em um projeto em que o seu início foi desenvolvido por terceiros.
Eu não sei lhe dizer com exatidão, pois não sei a diferença entre os 2 modelos.
Ainda sou iniciante na tecnologia (na verdade sou iniciante em programação, eu era da área de suporte a 2 meses atrás).

Conheço OO, pois meu curso está praticamente no fim(faltam apenas 2 matérias na faculdade), mas ainda não tenho experiência.

Quando eu utilizo Entity Framework eu tenho que adicionar aquele componente de Modelo de Dados de Entidade ADO.NET, correto?

Pelo que pesquisei na internet é isso que estou utilizando.

Poderia me explicar a diferença se não for isso?
GOSTEI 0
Fabio Mans

Fabio Mans

24/10/2009

Manda a tela onde você tem suas classes, assim eu consigo ver.
GOSTEI 0
Daniel Vieira

Daniel Vieira

24/10/2009


GOSTEI 0
Fabio Mans

Fabio Mans

24/10/2009

Mostra a tela com o arquivo Model.edmx aberta. Mas já deu para ver, é Entity Framework.  
GOSTEI 0
Daniel Vieira

Daniel Vieira

24/10/2009


GOSTEI 0
Fabio Mans

Fabio Mans

24/10/2009

Você pode criar uma classe ou um projeto Class Library e criar os métodos de retorno.   Veja dois exemplo. No primeiro retorno todos os Grupos e no segundo exemplo é feito a mesma consulta que você postou no chamado. Ambos preenchem um Grid.       namespace EntityChamado { public class Repositorio { public IQueryable<Grupo> ObterGrupos() { DevMediaEntities db = new DevMediaEntities(); return db.Grupo; }   public IQueryable<Produto> ObterProdutos(int codGrupoSubFamilia, int codGrupoSub, int codGrupo) {   DevMediaEntities db = new DevMediaEntities(); //Le os registros com os parametros dos 3 combos e preenche o GRID return db.Produto.Where( p => p.GrupoSubFamilia.codigoGrupoSub == codGrupoSub && p.GrupoSubFamilia.codigoGrupoSubFamilia == codGrupoSubFamilia && p.GrupoSubFamilia.codigoGrupo == codGrupo); } } }   Espero ter ajudado. Fabio
GOSTEI 0
Daniel Vieira

Daniel Vieira

24/10/2009

Então é só eu criar esta classe, e quando for preencher um grid atribuir ao seu datasource um dos 2 métodos?

ex:

grdProdutos.DataSource = myObj.ObterGrupos();

grdProdutos.DataSource = myObj.ObterProdutos(var1,var2,var3);

Eu preenchendo desta maneira não irei ter problemas com nome de campo?

No meu primeiro select eu estava com problema na navegação entre os campos:

var newProdutoFilter = (from p in db.Produto
                                        where (
                                        (p.GrupoSubFamilia.codigoGrupoSub == codGrupoSub) &&
                                        (p.GrupoSubFamilia.codigoGrupoSubFamilia == codGrupoSubFamilia) &&
                                        (p.GrupoSubFamilia.codigoGrupo == codGrupo))
                                        orderby p.codigo descending
                                        select new
                                        {
                                            p.codigo,
                                            p.descricao,
                                            p.descricaoReduzida,
                                            p.descricaoECF,
                                            p.UnidadeMedida.codigo, //este campo da erro de compilacao
                                            p.GrupoSubFamilia.GrupoSub.Grupo.codigo,  //este tambem
                                            p.GrupoSubFamilia.GrupoSub.codigoGrupoSub,
                                            p.GrupoSubFamilia.codigoGrupoSubFamilia,
                                            p.tipo,
                                            p.ativo
                                        });
                grdProduto.DataSource = newProdutoFilter;

Estes 2 campos dão erro por serem FK e seus nomes serem iguais ao campo código da tabela produto, devido a necessidade de eu navegar entre tabelas filhas para exibir seu conteúdo.
Com estes seus 2 métodos não irá dar erro?
Enquanto aguardo resposta vou aplicálos ao meu projeto.
Eu crio uma nova classe ou utilizo alguma das existentes?
Acho conveniente utilizar uma nova, vou fazer uma agora e testar o preenchimento de um grid.
GOSTEI 0
Daniel Vieira

Daniel Vieira

24/10/2009

Complementando a pergunta abaixo, implementei o seu método, mas continuo com o mesmo problema.
Meu grid não exibe os campos FK.

Vou postar uma screenshot da tela preenchida.
Criei uma classe exatamente como você postou, e no load do form chamei o evento ObterProdutos(1,1,48) que são parametros existentes na minha base.

Olhe o resultado:




Preenche todos os campos, exceto as FK, exatamente o problema que eu estava tendo antes (mas antes dava erro de compilacao no select)
GOSTEI 0
Fabio Mans

Fabio Mans

24/10/2009

O Grid é criado automaticamente ou você define os campos, nos exemplos que fiz retornou o campo PK
GOSTEI 0
Daniel Vieira

Daniel Vieira

24/10/2009

Não entendi a pergunta.

Eu adicionei o grid no form, e mudei o nome dos campos no Design - Name

Seria essa a pergunta?
GOSTEI 0
Fabio Mans

Fabio Mans

24/10/2009

Isso você adicionou o campo com o FK no Grid? Não é por isso que não aparece? Porque não tem a coluna com a chave primária.   Fabio
GOSTEI 0
Daniel Vieira

Daniel Vieira

24/10/2009

Fabio, eu adicionei ao Grid o BindingSource gerado automaticamente, puxando direto da tabela.
Esta na ScreenShot abaixo:




O que eu estou fazendo errado pra nao preencher os campos FK?
Ps: Se eu utilizar aquele metodo gerado automaticamente do Grid no load do form ele preenche corretamente, mas eu preciso utilizar filtros, por isso necessito do select.

O que eu preciso fazer pra preencher completamente o grid com aqueles metodos de sua classe?




GOSTEI 0
Fabio Mans

Fabio Mans

24/10/2009

E o código vem vazio?
GOSTEI 0
Daniel Vieira

Daniel Vieira

24/10/2009

Não preenche nenhum dos campos do grid que são FK, conforme screenshot mostrada alguns posts abaixo.

esse foi o motivo da minha abertura de chamado, preciso preencher o grid com os dados das FK.

GOSTEI 0
Fabio Mans

Fabio Mans

24/10/2009

Pelo que entendi no seu chamado sua dúvida seria como tirar o método da página e colocar em uma classe.   Sobre sua dúvida no Windows Forms eu não vou saber responder, eu testei com Web e deu certinho, ele carregou o campo FK.     codigo descricao comissao rentabilidade ativo codigoUsuario 1 TESTE 1,00 1,00 1 1 2 TESTE2 2,00 2,00 2 1   Fabio
GOSTEI 0
Daniel Vieira

Daniel Vieira

24/10/2009

Me desculpe se não fui muito claro na minha abertura de chamado, primeira vez que eu utilizo esse sistema!

Minha necessidade era realmente preencher o grid com todos os campos, inclusive os FK (que não estavam preenchendo).

Eu pedi ajuda a alguns colegas de faculdade que trabalham com a mesma tecnologia, e eles me disseram pra tirar da UI e colocar em uma classe, que retornando uma lista de objetos funcionaria.

Minha amiga me passou o seguinte exemplo:

//Classe Pessoa para ser usada na apresentação na DataGridView
public class Pessoa
{
    public string Nome
    {
        get;
        set;
    }
   
    public int Idade
    {
        get;
        set;
    }   
}

//Método para a apresentação e atualização dos dados na DataGridView
private void Atualiza()
{
    List<Pessoa> listaPessoa = new List<Pessoa>();

    foreach ("NomeDaTabela" p in this."NomeDaTabela")
    {
        Pessoa pes = new Pessoa();

        pes.Nome = p."NomePessoa";
        pes.Idade = p."IdadePessoa";       

        listaPessoa.Add(pes);
    }   
    this."NomeDoSeuDataGridView".DataSource = listaPessoa.ToList();   
}

Eu não entendi muito bem o exemplo dela, e resolvi abrir um chamado, tentando reunir o máximo de informações que eu tinha para facilitar o entendimento do problema. Acabei focando mais onde não devia. Peço desculpas.

Eu gostaria de informar que o exemplo pra preenchimento do Grid Grupo funcionou corretamente aqui também, está exibindo a chave estrangeira do usuário.

Mas o grid de produtos não esta exibindo nenhuma FK, nem a de usuario, que exibe no grid Grupo.

Abaixo vou postar o grid Grupo, pravoce ver que aqui tambem preenche.
Focamos agora no problema do Produto, pois principalmente nele eu preciso aplicar alguns filtros, e exatamente nele é que nao esta exibindo as FK. Faça um teste no seu sistema pra podermos verificar se o erro ocorre com o seu projeto WEB também.


GOSTEI 0
Fabio Mans

Fabio Mans

24/10/2009

André não é usual mostrar para o usuário os campos FK (código), como será este filtro?

GOSTEI 0
Daniel Vieira

Daniel Vieira

24/10/2009

Os campos FK que eu preciso exibir são principalmente os 3 códigos do Grupo, SubGrupo e Família ao qual o produto pertence. Também preciso exibir a UnidadeMedida.

O filtro são Grupo, SubGrupo, Familia, e tambem preciso ordenar decrescente por código de família.
GOSTEI 0
Fabio Mans

Fabio Mans

24/10/2009

Este filtro você faz no Grid mesmo? Eu não estou sabendo te ajudar porque não trababalhamos com Windows Forms não sei se você viu os chamados não atendem Windows Forms, estou fazendo de tudo para ajudar mas creio que está dúvida de ordenação pelo Grid eu não sei responder, não pode ser um Drop com os código e na hora que você estolhe o sistema filtra?   Fabio
GOSTEI 0
Daniel Vieira

Daniel Vieira

24/10/2009

Nossa não vi que vocês não atendiam Windows Forms...Meu projeto inteiro é windows forms...

Como eu faria esse filtro que você está indicando??

Eu na verdade preciso exibir todos os dados no grid, não importa muito como, pode ser de qualquer jeito, desde que apareça todos os campos, e eu possa ficar atualizando ele. Unico filtro realmente necessário seria o de grupo + subgrupo + familia, pro usuário ver a quantidade de registros agrupados, e cadastrar o que ainda está faltando.

Se de qualquer maneira eu preencher o grid está valendo.


GOSTEI 0
Daniel Vieira

Daniel Vieira

24/10/2009

Fabio, estava analisando as outras telas, e a de família está preenchendo as FKs.






Eu estou utilizando o seguinte método:

private void atualizarGridFamilia()
        {
            try
            {
                //Instancia da classe de conexão com o LINQ
                Entities db = new Entities();

                //Le o ID do item do combo atraves da property Value
                int codGrupoSub = Convert.ToInt32(cmbGrupoSub.SelectedValue);
                int codGrupo = Convert.ToInt32(cmbGrupo.SelectedValue);

                //Le os registros com os parametros dos 2 combos e preenche o GRID
                var newGrupoSubFilter = (from p in db.GrupoSubFamilia
                                         where (p.codigoGrupoSub == codGrupoSub && p.codigoGrupo == codGrupo)
                                         orderby p.codigoGrupoSubFamilia descending
                                         select new
                                         {
                                             p.codigoGrupoSubFamilia,
                                             p.codigoGrupo,
                                             p.codigoGrupoSub,
                                             p.descricao,
                                             p.comissao,
                                             p.rentabilidade,
                                             p.ativo
                                         });
                grdGrupoSubFamilia.DataSource = newGrupoSubFilter;
            }
            catch (Exception ex)
            {
                MessageBox.Show("Grid erro : \n"
                                + ex.Message);
            }
        }

No caso da Tabela de família, ele não exigiu navegação entre as tabelas filhas para se obter acesso as fks, porém o mesmo não acontece com a tabela de produto.
Seria problema na estrutura da base??





GOSTEI 0
Fabio Mans

Fabio Mans

24/10/2009

Pode ser, tente renomear os campos pelo Designer do edbmx para ver o que acontece.
GOSTEI 0
Daniel Vieira

Daniel Vieira

24/10/2009

Eu renomeei todos os campos que poderiam dar conflito de nomes.
O campo codigo da tabela de produtos eu nomeei codigoProduto.

Campo codigo da tabela de grupo nomeei codigoGrupo.

Nomeei também codigoUsuario.

Mas agora nem o códigoProduto que é PK da tabela de produtos está aparecendo no grid.Nem o campo codigoGrupo está aparecendo no gridGrupo.

Depois de renomear no designer do model.edmx tem que fazer alguma reconfiguração especial??

GOSTEI 0
Daniel Vieira

Daniel Vieira

24/10/2009

complementando a informacao abaixo...

Quando eu voltei o nome no designer pra codigo (tabela produto), que eh o mesmo nome do campo na base, voltou a preencher no grid...

A não ser que eu esteja renomeando errado...Eu dei botão direito em cima do campo no diagrama de classe do edmx.
GOSTEI 0
Daniel Vieira

Daniel Vieira

24/10/2009

Debuguei o método que você me passou no começo do chamado, e os campos estão com valor nulo.
Na screenshot da pra verificar melhor:


GOSTEI 0
Daniel Vieira

Daniel Vieira

24/10/2009

Utilizando o metodo default que o VS gera após criar o grid e adicionar a fonte de dados, preenche o grid inteiro corretamente.






O metodo é o padrão:

this.produtoTableAdapter.Fill(this.cONSTRUSYSDataSet271009.Produto);

pergunta:
existe a possibilidade de se fazer filtros nesse método?? (eu já estou desesperado)




GOSTEI 0
Daniel Vieira

Daniel Vieira

24/10/2009

this.produtoTableAdapter.FillByDaniel(this.cONSTRUSYSDataSet271009.Produto,2,1,48);

Construi um metodo FillBy proprio no designer do tableAdapter, coloquei ele pra receber alguns parametros.
Acabou dando certo, eu tenho o filtro, e tenho todos os campos, inclusive os FK.

Não sei se isso é o certo, mas vou utilizar por enquanto.

Poderei ter algum problema por estar preenchendo um grid (e atualizando ele apos insercao ou alteracao) dessa maneira??
GOSTEI 0
Fabio Mans

Fabio Mans

24/10/2009

Você criou o método utilizando DataSet tipado? Não foi com o Entity? Se sim não tem problema, porém você mudou de tecnologia para acessar os dados.   Fabio
GOSTEI 0
Daniel Vieira

Daniel Vieira

24/10/2009

na verdade esse metodo o Visual studio cria automaticamente ao se adicionar uma fonte de dados ao grid, entao eu tentei modificar...

Ainda gostaria de preencher com a tecnologia Entity Framework.

GOSTEI 0
Fabio Mans

Fabio Mans

24/10/2009

Verifique o XML da classe, botão direito do mouse no edbm e abrir com XML, veja se ele montou o PK    
GOSTEI 0
Daniel Vieira

Daniel Vieira

24/10/2009

 <Association Name="FK_Produto_UnidadeMedida">
          <End Role="UnidadeMedida" Type="CONSTRUSYSModel.Store.UnidadeMedida" Multiplicity="1" />
          <End Role="Produto" Type="CONSTRUSYSModel.Store.Produto" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="UnidadeMedida">
              <PropertyRef Name="codigo" />
            </Principal>
            <Dependent Role="Produto">
              <PropertyRef Name="unidadeMedida" />
            </Dependent>
          </ReferentialConstraint>
        </Association>


copiei de lá, está correto?
GOSTEI 0
Fabio Mans

Fabio Mans

24/10/2009

Está certo. Ele inclui, excluir, lista os produtos (exceto o fk) normalmente?   <Association Name="FK_Produto_UnidadeMedida">
          <End Role="UnidadeMedida" Type="CONSTRUSYSModel.Store.UnidadeMedida" Multiplicity="1" />
          <End Role="Produto" Type="CONSTRUSYSModel.Store.Produto" Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="UnidadeMedida">
              <PropertyRef Name="codigo" />
            </Principal>
            <Dependent Role="Produto">
              <PropertyRef Name="unidadeMedida" />
            </Dependent>
          </ReferentialConstraint>
        </Association>

GOSTEI 0
Daniel Vieira

Daniel Vieira

24/10/2009

sim, nunca tive problema com nenhum item, exceto que os campos fk que nao aparecem.

Procurando em foruns gringos, me disseram pra fazer isso:

var q = from p in db.Produto.Include("UnidadeMedida").Include("Usuario").Include("GrupoSubFamilia")
                    where
                    ((p.GrupoSubFamilia.codigoGrupo == codigoGrupo) &&
                    (p.GrupoSubFamilia.codigoGrupoSub == codigoGrupoSub) &&
                    (p.GrupoSubFamilia.codigoGrupoSubFamilia == codigoGrupoSubFamilia))
                    orderby p.codigoProduto descending
                    select new
                    {
                        p.codigoProduto,
                        p.descricao,
                        p.descricaoReduzida,
                        p.descricaoECF,
                        p.UnidadeMedida.codigoUnidadeMedida,
                        p.GrupoSubFamilia.codigoGrupo,
                        p.GrupoSubFamilia.codigoGrupoSub,
                        p.GrupoSubFamilia.codigoGrupoSubFamilia,
                        p.tipo,
                        p.ativo,
                        p.Usuario.codigo
                    };

            grdProduto.DataSource = q;
        }

Não funcionou adicionando eses include, mas depois de tanto mecher no código agora me falta somente 1 FK, a de UnidadeMedida.

Ps: Eu nao sei o que eu fiz pra aparecerem as outras FKs.


GOSTEI 0
Fabio Mans

Fabio Mans

24/10/2009

Apenas mudou a sintaxe. Tente montar outro arquivo .dbmx e refaça as queries, faça um projeto a parte e modifique até descobrir o motivo.
GOSTEI 0
Fabio Mans

Fabio Mans

24/10/2009

Conseguiu resolver? Posso fechar?
GOSTEI 0
Daniel Vieira

Daniel Vieira

24/10/2009

Na verdade não consegui, nem tentei refazer o projeto tambem...Estamos em uma fase crítica e com os prazos estourados. Avancei pra outra fase, deixei pra trás. Podemos concluir por hora, o chamado me ajudou a transferir os métodos em classe, embora eu continue com problemas no grid... Abro outro chamado futuramente, quando voltar no problema!
GOSTEI 0
Fabio Mans

Fabio Mans

24/10/2009

Posso fechar?
GOSTEI 0
POSTAR