Usuário com melhor resposta
Atualizando com desempenho

Pergunta
-
Olá Pessoal,
Tenho várias instruções de UPDATE para a mesma tabela, porém algumas delas codificadas em métodos separados.
Estou implementando da seguinte forma o primeiro bloco:If Not IsDBNull(drSQL_Enderecos(7).ToString()) Then ' CONSULTA E PARAMETROS 'preenche o DataTable, Fill 'inspeção dos dados do resultado da consulta no SQL SERVER Dim drSQL_CEP_unico_Localidade As DataRow If dtSQL_CEP_unico_Localidade.Rows.Count > 0 Then drSQL_CEP_unico_Localidade = dtSQL_CEP_unico_Localidade.Rows(0) 'UPDATE E PARAMETROS 'preenche o DataTable, Fill Else 'CONSULTA E PARAMETROS 'preenche o DataTable, Fill 'inspeção dos dados do resultado da consulta no SQL SERVER Dim drSQL_Logradouro As DataRow If dtSQL_Logradouro.Rows.Count > 0 Then drSQL_Logradouro = dtSQL_Logradouro.Rows(0) 'UPADATE E PARAMETROS 'preenche o DataTable, Fill Else ' SE O PEN_CEP FOR NULO => PEN_ANTIGO = 'INVALIDO' CEP_Invalido(drSQL_Enderecos(0).ToString(), "INVALIDO " & Endereco_Concatenado) End If End If Else ' SE O PEN_CEP FOR NULO => PEN_ANTIGO = 'INVALIDO' CEP_Invalido(drSQL_Enderecos(0).ToString(), "INVALIDO " & Endereco_Concatenado) End If End If Else ' SE O PEN_CEP FOR NULO => PEN_ANTIGO = 'INVALIDO' CEP_Invalido(drSQL_Enderecos(0).ToString(), "INVALIDO " & Endereco_Concatenado) End If
Minhas dúvidas são:
1) Existe a possibilidade de realizar um update só com os dados de duas ou mais consultas??
2) Quais são as melhores maneiras de se atualizar dados??
Solicito ajuda,
aguardo...
Magno Machado Borba |- Se o post foi util ou resposta nao esqueca de marcar.
Respostas
-
Olá Magno, me desculpe pela demora, estava meio enrolado em um projeto (para variar.. rs)
Bom vamos lá,
1-) Escrevi um thread para um outro colega do grupo, acho que irá satisfazer essa sua duvida -> http://social.msdn.microsoft.com/Forums/pt-BR/504/thread/2f321c65-7697-42f9-ac55-8915b84d7956
2-) No reader.Read, vc poed fazer com que ele receba uma entidade generica e devolva essa entidade preenchida, exemplo
public T PreencherEntidade()
{
reader.read()....
}
3-) Segue um exemplo usando reflection e NHibernate.public List<T> BuscarTodos(string tableName) { List<T> lista = new List<T>(); try { using (IDataReader reader = ExecuteReader("PROCEDURE")) { while (reader.Read()) { T entidade = Activator.CreateInstance<T>(); ((Entities.IEntityBase)entidade).BeginUpdate(); for (int i = 0; i < reader.FieldCount; i++) { if (!reader.IsDBNull(i)) { if (GetPropertyName(reader.GetName(i)).Equals(string.Empty)) { PropertyInfo pi = entidade.GetType().GetProperty(reader.GetName(i)); string tipo = reader.GetFieldType(i).Name.ToLower(); switch (tipo) { case "string": pi.SetValue(entidade, reader.GetString(i), null); break; case "int32": pi.SetValue(entidade, reader.GetInt32(i), null); break; case "decimal": pi.SetValue(entidade, reader.GetDecimal(i), null); break; case "datetime": pi.SetValue(entidade, reader.GetDateTime(i), null); break; case "boolean": pi.SetValue(entidade, reader.GetBoolean(i), null); break; default: break; } } else { PropertyInfo pi = entidade.GetType().GetProperty(GetPropertyName(reader.GetName(i))); object obj = ((ObjectHandle)Activator.CreateInstance(pi.PropertyType.Namespace, pi.PropertyType.FullName)).Unwrap(); ((Itau.Fase.Entities.EntityBase)obj).Id = reader.GetInt32(i); pi.SetValue(entidade, obj, null); } } } ((Entities.IEntityBase)entidade).EndUpdate(); lista.Add(entidade); } } return lista; } catch (Exception ex) { throw ex; } }
Att,
Nelson Borges - Analista de Sistemas- Sugerido como Resposta Nelson Borges sábado, 9 de maio de 2009 19:30
- Marcado como Resposta Magno Machado sábado, 9 de maio de 2009 23:44
Todas as Respostas
-
Magno,
1-)Bom não sei com esta estrutura sua solução, mas derepente seria melhor vc ter um unico método que executasse o comando no banco de dados, e esse método (genério) recebia as várias ações de atualizar decorrente dos processos.
2-) Uma maneira que encontrei a algum tempo para ganhar performance é usar o UpdateBatch do Ado, ou seja eu crio um lote de updates e disparo todos para o banco de dados, o UpdateBatch persiste os dados de todos os registros alterados enquanto o Update persite os dados apenas do registro atual.
Mais informações: http://davidhayden.com/blog/dave/archive/2006/01/05/2665.aspx or http://www.dotnetspider.com/resources/4467-Multiple-Inserts-Single-Round-trip-using-ADO-NE.aspx
Abraço,
Nelson Borges - Analista de Sistemas -
-
Magno,
Segue um exemplo de uma classe DAL genérica com 2 métodos um para buscar os dados e outro para atualizar, detalhe no método atualizar vc pode ir preenchendo de acordo com os artigos que te passei no thread acima, esta é apenas um simples exemplo feito no notepad :), por isso desconsidere ai a falta de uso dos construtores das classes como command e etc :)
//Classe de acesso a dados Genérica public class AcessoDadosBase<T> { //Exemplo de um método genérico para popular um entidade através do banco de dados. public T Buscar(string procedure, List<SqlParameter> param) { T entidade = Activator.CreateInstance<T>(); using (IDataReader reader = ExecuteReader(procedure, param)) { if (reader.Read()) { /// Preenche a entidade(T) - Neste caso vc pode usar aqui o NHibernate ou reflection } } } //Método Genério para atualizar public void Altualizar(string procedure, List<SqlParameter> param) { //Aqui dentro vc criaria os DataAdapter com o UpdateBath SqlCommand command = new SqlCommand();
Espero ter ajudado.
command.CommandType = CommandType.StoredProcedure; command.Parameters.AddRange(param.ToArray()); adapter.UpdateCommand = command; adapter.UpdateBatchSize = 2; ///... } }
Nelson Borges - Analista de Sistemas -
Olá Nelson,
Neste método:
* veja o comentário em negrito (minha dúvida).
//Exemplo de um método genérico para popular um entidade através do banco de dados.
public T Buscar(string procedure, List<SqlParameter> param)
{
T entidade = Activator.CreateInstance<T>();
using (IDataReader reader = ExecuteReader(procedure, param)) // * A procedure pode ser uma query ou uma SP ? pode explicar essa linha?
{
if (reader.Read())
{
/// Preenche a entidade(T) - Neste caso vc pode usar aqui o NHibernate ou reflection
}
}
}
Desde já agradeço! Aguardo resposta.
Magno Machado Borba |- Se o post foi util ou resposta nao esqueca de marcar. -
-
Olá Nelson,
Antes de tudo, gostaria de agradecer sua ajuda. Agora, seguem as dúvidas:
1) Poderia esclarecer/explicar sobre o preenchimento usando uma classe Entidade... isso seria apenas para atribuir os objetos para parametros...?
2) O que pode ser feito depois do reader.Read em métodos genéricos?
3) Se nao fosse usado Linq, NHibernate ou reflection, como seria esse método?
Neste trecho de código a que estou me referindo:
if (reader.Read())
{
/// Preenche a entidade(T) - Neste caso vc pode usar aqui o NHibernate ou reflection
}
Aguardo ajuda
Magno Machado Borba |- Se o post foi util ou resposta nao esqueca de marcar. -
-
Olá Magno, me desculpe pela demora, estava meio enrolado em um projeto (para variar.. rs)
Bom vamos lá,
1-) Escrevi um thread para um outro colega do grupo, acho que irá satisfazer essa sua duvida -> http://social.msdn.microsoft.com/Forums/pt-BR/504/thread/2f321c65-7697-42f9-ac55-8915b84d7956
2-) No reader.Read, vc poed fazer com que ele receba uma entidade generica e devolva essa entidade preenchida, exemplo
public T PreencherEntidade()
{
reader.read()....
}
3-) Segue um exemplo usando reflection e NHibernate.public List<T> BuscarTodos(string tableName) { List<T> lista = new List<T>(); try { using (IDataReader reader = ExecuteReader("PROCEDURE")) { while (reader.Read()) { T entidade = Activator.CreateInstance<T>(); ((Entities.IEntityBase)entidade).BeginUpdate(); for (int i = 0; i < reader.FieldCount; i++) { if (!reader.IsDBNull(i)) { if (GetPropertyName(reader.GetName(i)).Equals(string.Empty)) { PropertyInfo pi = entidade.GetType().GetProperty(reader.GetName(i)); string tipo = reader.GetFieldType(i).Name.ToLower(); switch (tipo) { case "string": pi.SetValue(entidade, reader.GetString(i), null); break; case "int32": pi.SetValue(entidade, reader.GetInt32(i), null); break; case "decimal": pi.SetValue(entidade, reader.GetDecimal(i), null); break; case "datetime": pi.SetValue(entidade, reader.GetDateTime(i), null); break; case "boolean": pi.SetValue(entidade, reader.GetBoolean(i), null); break; default: break; } } else { PropertyInfo pi = entidade.GetType().GetProperty(GetPropertyName(reader.GetName(i))); object obj = ((ObjectHandle)Activator.CreateInstance(pi.PropertyType.Namespace, pi.PropertyType.FullName)).Unwrap(); ((Itau.Fase.Entities.EntityBase)obj).Id = reader.GetInt32(i); pi.SetValue(entidade, obj, null); } } } ((Entities.IEntityBase)entidade).EndUpdate(); lista.Add(entidade); } } return lista; } catch (Exception ex) { throw ex; } }
Att,
Nelson Borges - Analista de Sistemas- Sugerido como Resposta Nelson Borges sábado, 9 de maio de 2009 19:30
- Marcado como Resposta Magno Machado sábado, 9 de maio de 2009 23:44