DataTable ou SqlDataReader

15/04/2010

0

Boa tarde galera,

estou fazendo minha classe de acesso a dados e uma de conexao.

Na classe de conexao eu tenho um metodo que lista registros de uma determinada tabela.

Dúvida:
Qual a melhor forma de devolver os dados: SqlDataReader ou DataTable ?

Qual é o mais rápido para trabalhar ?


OBS: Não gostaria de usar o SqlDataReader em outra camada, pois não qro utilizar a System.Data.SqlClient, acho que não faz parte dessa camanda, e sim somente da classe do DB.


Falow.
Tiago Melantonio

Tiago Melantonio

Responder

Posts

15/04/2010

Alexandre Lima.

Tiago,

Existem duas formas de trabalhar com acesso à dados(no seu caso):

Conectado - SqlDataReader

Desconectado - DataSet e/ou DataTable usando TableAdapter para acesso ao banco


Tranbalhando de forma conectada à base de dados, é necessário uma conexão ativa com o banco de dados, isso pode gerar um pouco mais de processamento quando a massa de dados é relativamente grande.

Trabalhando de forma desconectada além de ser uma forma elegante de trabalhar com dados no .Net não é necessário uma conexão ativa durante a manipulação de dados.


Aconselho pesquisar sobre alguma ferramenta de ORM(Linq to Sql, Entity Framework, Nhibernate etc), isso irá  facilitar muito o desenvolvimento de sua aplicação.








Responder

16/04/2010

Netasper

Quem é que não gosta de fazer o menor esforço quando precisa codificar. Quanto se trata de acessar dados com VB .NET ou ASP .NET temos duas opções claras : DataSet e DataReader. E em se falando de pouco esforço quanto a codificação , com o DataSet podemos fazer o acesso basicamente com 3 linhas de código. Basta preencher o DataSet e a seguir fazer a interação usando um loop. Mas e quanto ao desempenho ? Geralmente o desempenho é um requisito que vem em primeiro lugar , quer em aplicações Windows Forms quer em aplicações Web. Quando se fala em desempenho a utilização de um DataReader leva vantagem sobre um DataSet. Com um DataReader você tem acesso aos dados assim que o objeto fica disponível e não necessita esperar , como no caso do DataSet , o seu preenchimento. As vantagens do DataReader A seguir temos um código que preenche um DataSet com o resultado de uma tabela e exibe o primeiro campo em cada linha:0  SqlConnection conn = new SqlConnection(connectionString);
 SqlDataAdapter da = new SqlDataAdapter ("select * from tabela;",conn);

 DataSet ds = new DataSet();  da.Fill(ds);

 foreach (DataRow dr in ds.Tables[0].Rows)
 {
     Console.WriteLine(dr[0].ToString());
 } Dim conn As New SqlConnection(connectionString)
Dim da As New SqlDataAdapter("select * from tabela;", conn)

Dim ds As New DataSet()
da.Fill(ds)

Dim dr As DataRow
For Each dr In ds.Tables(0).Rows
    Console.WriteLine(dr(0).ToString())
Next dr C# VB.NET Observando o código você pode notar que a inspeção dos dados feita no loop foreach começa somente após o DataSet ter sido preenchido. Não dá para realizar outra tarefa enquanto o DataSet estiver sendo preenchido. Vamos ver agora o código que realiza a mesma tarefa usando um DataReader:  SqlConnection con = new SqlConnection(connectionString);
 SqlCommand cmd = new SqlCommand("select * from tabela", con);

 cmd.Connection.Open();

 SqlDataReader dr =   cmd.ExecuteReader(CommandBehavior.CloseConnection);

 while(dr.Read())  
 {
   Console.WriteLine(dr.GetString(0));
 }

 dr.Close();
 con.Close();
  Dim con As New SqlConnection(connectionString)
Dim cmd As New SqlCommand("select * from tabela", con)

cmd.Connection.Open()

Dim dr As SqlDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection)

While dr.Read()
   Console.WriteLine(dr.GetString(0))
End While

dr.Close()
con.Close() C# VB .NET Neste caso a inspeção dos dados é feita tão logo os dados estiverem disponíveis através de um loop While , onde dr.Read() retorna false se não encontrar dados. O DataReader armazena um resultado por vez no cliente , e , com isto reduz o uso de memória e recursos do sistema. É óbvio que dependendo da situação somente um DataSet irá resolver a questão : serializar o resultado ou passar uma consulta para a próxima camada da sua aplicação , vai requerer uma coleção e um DataSet fornece um modelo adequado para estas tarefas. Na maioria das consultas empregadas nas aplicações Web , onde os dados é pesquisado , exibido e então descartado um DataReader irá aumentar o desempenho da sua aplicação de forma significativa. Então usar um DataReader é mais rápido que usar um DataSet . Certo ?   Bem , sim e depende... Será que não existe um modo de otimizar o desempenho de um DataSet para justificar sua utilização ? Sim , existe e eu vou mostrar como você pode fazer isto. Antes vou mostrar o porque você quereria usar um DataSet. Os DataSet possuem um conjunto de funcionalidades que os DataReaders não possuem , dentre eles destacamos: Relacionamento Mestre-Detalhe com verificação de integridade Podemos efetuar operações com as colunas do lado do cliente (Soma, Média , etc..) que podem ser persistidas mesmo que os dados se alterem. Ordenação e Filtragem de dados no lado do cliente sem a necessidade de um round-trip ao Banco de dados Uma variedade de opções na vinculação de dados: DataGrid , WinForms e .NET Controls. Integração com o DataAdapter para atualização automática de atualizações. Poder ler e escrever diretamente uma representação XML de dados relacionados. Escolher usar um DataReader somente olhando a questão do desempenho irá fazer com que você não tenha acesso a estas funcionalidades. Existem outros aspectos negativos em um DataReader que talvez o façam mudar de idéia.  Em sistemas multiusuários , enquanto  os DataSets/DataAdapters liberam suas conexões e bloqueios assim que o preenchimento via método Fill termina , os DataReaders estão gerenciando a conexão e qualquer bloqueio aberto durante todo o tempo que durar o loop de inspeção de dados. (dr.Read()). Isto pode levar a uma maior contenção do seu banco de dados e com isto diminuir o desempenho . A única justificativa para usar um DataSet seria então melhorar seu desempenho. Melhorando o desempenho de um DataAdapter Você pode aproximar o desempenho de um DataAdapter de um DataReader desativando temporariamente algumas das funcionalidades avançadas padrão de um DataSet durante o processamento. Creio que os pontos chave em matéria de desempenho durante o processamento de um DataSet são a integridade referencial e a indexação que o DataSet usa para manter os dados internamente. Abaixo temos um código que mostra o preenchimento de um Dataset , via DataAdapter , que possui duas tabelas do banco de dados Northwind.mdb  : Customers e Employees DataSet ds= new DataSet();

string strConn="Server=(local);dataBase=Northwind;user id=sa;password=;";

SqlConnection cn = new SqlConnection(strConn);

string strSQL="select * from Customers;select * from employees";

cn.Open();

SqlDataAdapter da = new SqlDataAdapter( strSQL,cn);

ds.Tables.Add("Customers");
ds.Tables.Add("Employees");

ds.EnforceConstraints =false;

ds.Tables["Customers"].BeginLoadData();
da.Fill(ds.Tables["Customers"]);
ds.Tables["Customers"].EndLoadData(); ds.Tables["Employees"].BeginLoadData();
da.Fill(ds.Tables["Employees"]);
ds.Tables["Employees"].EndLoadData();

dataGrid1.DataSource=ds.Tables["Customers"];
dataGrid2.DataSource=ds.Tables["Employees"];

cn.Close(); Neste código tomamos algumas medidas para melhorar o desempenho do DataSet. Vejamos quais: A primeira delas foi definir a propriedade - EnforceConstraints - como false ; isto desabilita a verificação das restrições durante a operação e pode tornar a operação mais rápida. Você pode voltar a definir o valor como True depois que os dados forem retornados dentro um loop try/Catch e tratando a exceção ConstraintException. Outro fator que onera o desempenho de um DataSet é o estabelecimento de uma chave primária. Podemos também desabilitar temporariamente a indexação e notificação interna. Para isto fazemos o seguinte: 1- Executamos o método BeginLoadData antes de usar o método Fill para desabilitar a notificação , indexação.
2- Executamos o método EndLoadData depois de usar o método Fill para habilitar a indexação a notificação. Estes métodos são membros da classe DataTable e por isso você vai precisar chamá-los para a DataTable particular que você esta preenchendo. Com isto melhoramos o desempenho do DataSet e com isto justificamos sua utilização afim de podermos usar seus recursos.
Responder

20/04/2010

Danilo Mendes

Amigo, já que você fala em camadas e classes, pq não avançar para uma outra coisa mais madura tipo o nHibernate ou até mesmo o EntityFramework?

Hoje pouca gente gente usa isso (dataset ou datareader) em sistemas novos por trazerem vários problemas na hora da manutenção.
Responder

20/04/2010

Tiago Melantonio

Mas muitos lugares ainda usam o FrameWork 2.0, gostaria de usar procedures e não trabalhar como o linq, pois qualquer alteração precisa gerar uma nova dll.

Já trabalhei com o LINQ e não gostei muito da performace dele, acho q não tem nada igual ao SqlClient.
Responder

23/04/2010

Netasper

Amigo Danilo, vc esta inteiramente equivocado. Falar em maturidade com Linq e nHibernate é brincadeira ne?!?! Procure ler um pouco mais sobre grandes empresas e sistemas robustos e veja qual usa Linq ou mesmo nHibernate. Nenhuma.... Geralmente, quando a empresa tem condições, eles desenvolvem seu proprio framework. Mas na maioria das vezes é usado Enterprise Library. DAAB.     []s
Responder

Assista grátis a nossa aula inaugural

Assitir aula

Saiba por que programar é uma questão de
sobrevivência e como aprender sem riscos

Assistir agora

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar