Pular para o conteúdo principal

Record Set

Descrição​

O Record Set é uma representação em memória de dados tabulares. Ele tem a mesma forma do resultado de uma consulta SQL (linhas e colunas), mas pode ser criado, lido e modificado por qualquer parte do sistema, sem depender de uma conexão aberta com o banco.

Ferramentas de interface de usuário com vínculo a dados (data-aware UI) esperam estruturas nesse formato. Com um Record Set, a aplicação mantém essa conveniência e, ao mesmo tempo, ganha um lugar onde regras de negócio e validações podem operar sobre os dados, em vez de ficarem em stored procedures ou espalhadas pela interface.

É o padrão por trás de estruturas como DataSet e DataTable do .NET, ResultSet desconectado do JDBC (RowSet) e dataframes em linguagens de análise de dados.

Problemas que resolve​

  • Interfaces data-aware precisam de dados tabulares, mas a lógica de negócio não deve ficar na própria tela.
  • Validações e cálculos mais ricos que checagens simples não têm onde viver sem stored procedures.
  • Resultados de consulta presos a uma conexão aberta não podem ser passados adiante nem modificados com segurança.

Quando usar​

  • Quando a aplicação é centrada em dados relacionais e usa componentes de UI vinculados a dados.
  • Em conjunto com Table Module ou Transaction Script, que operam naturalmente sobre dados tabulares.
  • Para relatórios e telas de manutenção simples (CRUD) em que um modelo de objetos seria exagero.

Quando evitar​

  • Quando a lógica de domínio é complexa e se beneficia de um Domain Model, pois o Record Set empurra para um estilo orientado a tabelas.
  • Quando a camada de domínio não deve conhecer a estrutura do banco, já que o Record Set a reproduz.
  • Quando os conjuntos de dados são muito grandes e o custo de mantê-los todos em memória é inaceitável.

Trade-offs​

GanhoCusto / Risco
Integração direta com ferramentas de UI vinculadas a dadosLógica de negócio fica com estrutura de tabela, sem objetos de domínio expressivos
Dados desconectados que podem ser manipulados e repassadosAcesso por nome de coluna tende a ser frágil e pouco tipado
Rapidez de desenvolvimento em aplicações centradas em dadosCamada de domínio acoplada ao esquema do banco
Permite regras de negócio fora de stored proceduresPode consumir muita memória com grandes volumes
  • Consistência: muitas implementações rastreiam alterações de linhas para sincronizar com o banco, o que ajuda na atualização, mas exige cuidado com concorrência.
  • Desempenho: um conjunto desconectado evita ir ao banco repetidamente.

Diagrama​

A interface e a lógica de negócio operam sobre o mesmo RecordSet, que é carregado do Database, mas existe em memória de forma independente.

Exemplo​

Uma tela de pedidos exibe linhas vindas do banco e uma regra de negócio calcula o total sobre elas antes de a tela ser vinculada ao mesmo conjunto.

using System.Data;

DataTable orders = new DataTable("Orders");
orders.Columns.Add("Id", typeof(int));
orders.Columns.Add("Quantity", typeof(int));
orders.Columns.Add("UnitPrice", typeof(decimal));

orders.Rows.Add(1, 2, 10.50m);
orders.Rows.Add(2, 5, 3.00m);

// Regra de negócio operando sobre o Record Set
decimal total = 0;
foreach (DataRow row in orders.Rows)
total += (int)row["Quantity"] * (decimal)row["UnitPrice"];

// A mesma tabela pode ser vinculada a uma grade de UI
// grid.DataSource = orders;

Padrões relacionados​

  • Table Module — organiza a lógica de domínio por tabela e consome o Record Set como estrutura de dados.
  • Transaction Script — scripts também operam bem sobre dados tabulares.
  • Domain Model — a alternativa orientada a objetos, que substitui o Record Set por objetos ricos.
  • Table Data Gateway — costuma devolver um Record Set como resultado das consultas.
  • Data Transfer Object — também transporta dados, mas com estrutura fixa e voltada à transferência entre processos.

Referência​