Fórum Atualizar DataGridView usando Linq com C# (tabela com FK) #10330
24/10/2009
0
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
Curtir tópico
+ 0Posts
26/10/2009
Fabio Mans
Gostei + 0
26/10/2009
Daniel Vieira
/****** 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
26/10/2009
Fabio Mans
Gostei + 0
26/10/2009
Daniel Vieira
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
26/10/2009
Fabio Mans
Gostei + 0
26/10/2009
Daniel Vieira
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
26/10/2009
Fabio Mans
Gostei + 0
26/10/2009
Daniel Vieira
Gostei + 0
26/10/2009
Fabio Mans
Gostei + 0
26/10/2009
Daniel Vieira
Gostei + 0
26/10/2009
Fabio Mans
Gostei + 0
26/10/2009
Daniel Vieira
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
26/10/2009
Daniel Vieira
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
26/10/2009
Fabio Mans
Gostei + 0
26/10/2009
Daniel Vieira
Eu adicionei o grid no form, e mudei o nome dos campos no Design - Name
Seria essa a pergunta?
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)