Compartilhar via


Associar objetos como fontes de dados em aplicativos .NET Framework usando o Visual Studio

Observação

A DataSet classe e as classes relacionadas são tecnologias herdadas do .NET Framework do início dos anos 2000 que permitem que os aplicativos trabalhem com dados na memória enquanto os aplicativos são desconectados do banco de dados. As tecnologias são especialmente úteis para aplicativos que permitem que os usuários modifiquem dados e persistam as alterações no banco de dados. Embora os conjuntos de dados sejam uma tecnologia comprovadamente bem-sucedida, a abordagem recomendada para novos aplicativos .NET é usar o Entity Framework Core. O Entity Framework fornece uma maneira mais natural de trabalhar com dados tabulares como modelos de objeto e tem uma interface de programação mais simples.

O Visual Studio fornece ferramentas de tempo de design para trabalhar com objetos personalizados como a fonte de dados em seu aplicativo. Quando você deseja armazenar dados de um banco de dados em um objeto associado aos controles de interface do usuário, a abordagem recomendada é usar o Entity Framework para gerar a classe ou classes. O Entity Framework gera automaticamente todo o código padrão de rastreamento de alterações, o que significa que todas as alterações nos objetos locais são automaticamente persistidas no banco de dados ao chamar AcceptChanges no objeto DbSet. Para obter mais informações, consulte a Documentação do Entity Framework.

Dica

As abordagens de associação de objeto neste artigo só devem ser consideradas se o aplicativo já estiver baseado em conjuntos de dados. Você também pode usar essas abordagens se já estiver familiarizado com conjuntos de dados e os dados que você processará forem tabulares e não muito complexos ou muito grandes. Para obter um exemplo ainda mais simples, envolvendo o carregamento de dados diretamente em objetos usando um DataReader e atualizando manualmente a interface do usuário sem vinculação de dados, consulte Criar um aplicativo de dados simples usando ADO.NET.

Requisitos de objeto

O único requisito para que objetos personalizados funcionem com as ferramentas de design de dados no Visual Studio é que o objeto precise de pelo menos uma propriedade pública.

Geralmente, objetos personalizados não exigem interfaces, construtores ou atributos específicos para atuar como uma fonte de dados para um aplicativo. No entanto, se você quiser arrastar o objeto da janela Fontes de Dados para uma superfície de design para criar um controle vinculado a dados e, se o objeto implementar a interface ITypedList ou a interface IListSource, o objeto deverá ter um construtor padrão. Caso contrário, o Visual Studio não poderá instanciar o objeto de fonte de dados e exibirá um erro ao arrastar o item para a superfície de design.

Exemplos de como usar objetos personalizados como fontes de dados

Embora existam inúmeras maneiras de implementar sua lógica de aplicativo ao trabalhar com objetos como uma fonte de dados, para bancos de dados SQL há algumas operações padrão que podem ser simplificadas usando os objetos TableAdapter gerados pelo Visual Studio. Esta página explica como implementar esses processos padrão usando TableAdapters. Ele não se destina como um guia para criar seus objetos personalizados. Por exemplo, você normalmente executará as seguintes operações padrão, independentemente da implementação específica de seus objetos ou da lógica do aplicativo:

  • Carregando dados em objetos (normalmente de um banco de dados).

  • Criar uma coleção tipada de objetos.

  • Adicionando objetos e removendo objetos de uma coleção.

  • Exibindo os dados do objeto para os usuários em um formulário.

  • Alterando/editando os dados em um objeto.

  • Salvar dados de objetos de volta para o banco de dados.

Carregar dados em objetos

Para este exemplo, você carrega dados em seus objetos usando TableAdapters. Por padrão, TableAdapters são criados com dois tipos de métodos que buscam dados de um banco de dados e preenchem tabelas de dados.

  • O TableAdapter.Fill método preenche uma tabela de dados existente com os dados retornados.

  • O TableAdapter.GetData método retorna uma nova tabela de dados preenchida com dados.

A maneira mais fácil de carregar seus objetos personalizados com dados é chamar o TableAdapter.GetData método, fazer loop pela coleção de linhas na tabela de dados retornada e preencher cada objeto com os valores em cada linha. Você pode criar um GetData método que retorna uma tabela de dados populada para qualquer consulta adicionada a um TableAdapter.

Observação

O Visual Studio nomeia as consultas Fill TableAdapter e GetData , por padrão, mas você pode alterar esses nomes para qualquer nome de método válido.

O exemplo a seguir mostra como percorrer as linhas em uma tabela de dados e preencher um objeto com dados:

private void LoadCustomers()
{
    NorthwindDataSet.CustomersDataTable customerData = 
        customersTableAdapter1.GetTop5Customers();
    
    foreach (NorthwindDataSet.CustomersRow customerRow in customerData)
    {
        Customer currentCustomer = new Customer();
        currentCustomer.CustomerID = customerRow.CustomerID;
        currentCustomer.CompanyName = customerRow.CompanyName;

        if (customerRow.IsAddressNull() == false)
        {
            currentCustomer.Address = customerRow.Address;
        }

        if (customerRow.IsCityNull() == false)
        {
            currentCustomer.City = customerRow.City;
        }

        if (customerRow.IsContactNameNull() == false)
        {
            currentCustomer.ContactName = customerRow.ContactName;
        }

        if (customerRow.IsContactTitleNull() == false)
        {
            currentCustomer.ContactTitle = customerRow.ContactTitle;
        }

        if (customerRow.IsCountryNull() == false)
        {
            currentCustomer.Country = customerRow.Country;
        }

        if (customerRow.IsFaxNull() == false)
        {
            currentCustomer.Fax = customerRow.Fax;
        }

        if (customerRow.IsPhoneNull() == false)
        {
            currentCustomer.Phone = customerRow.Phone;
        }

        if (customerRow.IsPostalCodeNull() == false)
        {
            currentCustomer.PostalCode = customerRow.PostalCode;
        }

        if (customerRow.IsRegionNull() == false)
        {
            currentCustomer.Region = customerRow.Region;
        }

        LoadOrders(currentCustomer);
        customerBindingSource.Add(currentCustomer);
    }
}

Criar uma coleção de objetos com tipo definido

Você pode criar classes de coleção para seus objetos ou usar as coleções tipadas que são fornecidas automaticamente pelo componente BindingSource.

Quando você está criando uma classe de coleção personalizada para objetos, sugerimos que você herde de BindingList<T>. Essa classe genérica fornece funcionalidade para administrar sua coleção, bem como a capacidade de gerar eventos que enviam notificações para a infraestrutura de associação de dados no Windows Forms.

A coleção gerada automaticamente em BindingSource usa um BindingList<T> para a respectiva coleção tipada. Se o aplicativo não exigir funcionalidade adicional, você poderá manter sua coleção dentro do BindingSource. Para obter mais informações, consulte a List propriedade da BindingSource classe.

Observação

Se sua coleção exigir funcionalidade não fornecida pela implementação base do BindingList<T>, você deverá criar uma coleção personalizada para que possa adicionar à classe conforme necessário.

O seguinte código mostra como criar a classe para uma coleção fortemente tipada de objetos Order:

/// <summary>
/// A collection of Orders
/// </summary>
public class Orders: System.ComponentModel.BindingList<Order>
{
    // Add any additional functionality required by your collection.
}

Adicionar objetos a uma coleção

Você adiciona objetos a uma coleção chamando o Add método de sua classe de coleção personalizada ou da BindingSource.

Observação

O Add método é fornecido automaticamente para sua coleção personalizada quando você herda de BindingList<T>.

O código a seguir mostra como adicionar objetos à coleção tipada em um BindingSource:

Customer currentCustomer = new Customer();
customerBindingSource.Add(currentCustomer);

O código a seguir mostra como adicionar objetos a uma coleção tipada que herda de BindingList<T>:

Observação

Neste exemplo, a Orders coleção é uma propriedade do Customer objeto.

Order currentOrder = new Order();
currentCustomer.Orders.Add(currentOrder);

Remover objetos de uma coleção

Você remove objetos de uma coleção chamando o método Remove ou o método RemoveAt de sua classe de coleção personalizada ou de BindingSource.

Observação

Os métodos Remove e RemoveAt são fornecidos automaticamente para sua coleção personalizada quando você herda de BindingList<T>.

O código a seguir mostra como localizar e remover objetos da coleção tipada em um BindingSource usando o método RemoveAt.

int customerIndex = customerBindingSource.Find("CustomerID", "ALFKI");
customerBindingSource.RemoveAt(customerIndex);

Exibir dados de objeto para usuários

Para exibir os dados em objetos para os usuários, crie uma fonte de dados de objeto usando o assistente de Configuração da Fonte de Dados e arraste todo o objeto ou as propriedades individuais para o formulário da janela Fontes de Dados .

Modificar os dados em objetos

Para editar dados em objetos personalizados associados a dados aos controles do Windows Forms, basta editar os dados no controle associado (ou diretamente nas propriedades do objeto). A arquitetura de associação de dados atualiza os dados no objeto.

Se o aplicativo exigir o acompanhamento das alterações e a reversão das alterações propostas em seus valores originais, você deverá implementar essa funcionalidade no modelo de objeto. Para obter exemplos de como as tabelas de dados acompanham as alterações propostas, consulte DataRowState, HasChangese GetChanges.

Salvar dados em objetos de volta para o banco de dados

Salve os dados de volta no banco de dados passando os valores do objeto para os métodos DBDirect do TableAdapter.

O Visual Studio cria métodos DBDirect que podem ser executados diretamente no banco de dados. Esses métodos não exigem objetos DataSet ou DataTable.

Método TableAdapter DBDirect Descrição
TableAdapter.Insert Adiciona novos registros a um banco de dados, permitindo que você passe valores de coluna individuais como parâmetros de método.
TableAdapter.Update Atualiza registros existentes em um banco de dados. O método Update usa valores de coluna originais e novos como parâmetros de método. Os valores originais são usados para localizar o registro original e os novos valores são usados para atualizar esse registro.

O método TableAdapter.Update também é usado para reconciliar as alterações em um conjunto de dados de volta ao banco de dados, usando um DataSet, DataTable, DataRow ou matriz de DataRows como parâmetros do método.
TableAdapter.Delete Exclui registros existentes do banco de dados com base nos valores de coluna originais passados como parâmetros de método.

Para salvar dados de uma coleção de objetos, faça loop pela coleção de objetos (por exemplo, usando um loop for-next). Envie os valores de cada objeto para o banco de dados usando os métodos DBDirect do TableAdapter.

O exemplo a seguir mostra como usar o TableAdapter.Insert método DBDirect para adicionar um novo cliente diretamente ao banco de dados:

private void AddNewCustomers(Customer currentCustomer)
{
    customersTableAdapter.Insert( 
        currentCustomer.CustomerID, 
        currentCustomer.CompanyName, 
        currentCustomer.ContactName, 
        currentCustomer.ContactTitle, 
        currentCustomer.Address, 
        currentCustomer.City, 
        currentCustomer.Region, 
        currentCustomer.PostalCode, 
        currentCustomer.Country, 
        currentCustomer.Phone, 
        currentCustomer.Fax);
}