Partilhar via


Vinculação de dados

O LINQ to SQL oferece suporte à associação a controles comuns, como controles de grade. Especificamente, o LINQ to SQL define os padrões básicos para vinculação a uma grade de dados e manipulação da vinculação mestre-detalhe, tanto no que diz respeito à exibição quanto à atualização.

Princípio subjacente

LINQ to SQL traduz consultas LINQ para SQL para execução em um banco de dados. Os resultados são fortemente digitados.IEnumerable Como esses objetos são objetos CLR (Common Language Runtime) comuns, a vinculação de dados de objetos comuns pode ser usada para exibir os resultados. Por outro lado, as operações de alteração (inserções, atualizações e exclusões) exigem etapas adicionais.

Operação

A vinculação implícita aos controles do Windows Forms é realizada implementando IListSourceo . As fontes de dados genéricas Table<TEntity> (Table<T> em C# ou Table(Of T) em Visual Basic) e genéricas DataQuery foram atualizadas para implementar IListSourceo . Os mecanismos de vinculação de dados da interface do usuário (UI) (Windows Forms e Windows Presentation Foundation) testam se a fonte de dados implementa IListSourceo . Portanto, escrever uma afetação direta de uma consulta a uma fonte de dados de um controle chama implicitamente a geração de coleção LINQ to SQL, como no exemplo a seguir:

DataGrid dataGrid1 = new DataGrid();
DataGrid dataGrid2 = new DataGrid();
DataGrid dataGrid3 = new DataGrid();

var custQuery =
    from cust in db.Customers
    select cust;
dataGrid1.DataSource = custQuery;
dataGrid2.DataSource = custQuery;
dataGrid2.DataMember = "Orders";

BindingSource bs = new BindingSource();
bs.DataSource = custQuery;
dataGrid3.DataSource = bs;
Dim dataGrid1 As New DataGrid()
Dim dataGrid2 As New DataGrid()
Dim dataGrid3 As New DataGrid()

Dim custQuery = _
    From cust In db.Customers _
    Select cust

dataGrid1.DataSource = custQuery
dataGrid2.DataSource = custQuery
dataGrid2.DataMember = "Orders"

Dim bs = _
    New BindingSource()
bs.DataSource = custQuery
dataGrid3.DataSource = bs

O mesmo ocorre com o Windows Presentation Foundation:

ListView listView1 = new ListView();
var custQuery2 =
    from cust in db.Customers
    select cust;

ListViewItem ItemsSource = new ListViewItem();
ItemsSource = (ListViewItem)custQuery2;
Dim listView1 As New ListView()
Dim custQuery2 = _
From cust In db.Customers _
Select cust

Dim ItemsSource As New ListViewItem
ItemsSource = custQuery2

As gerações de coleção são implementadas por genéricos Table<TEntity> e genéricos DataQuery em GetList.

Implementação IListSource

O LINQ to SQL implementa IListSource em dois locais:

  • A fonte de dados é um Table<TEntity>: LINQ to SQL navega na tabela para preencher uma DataBindingList coleção que mantém uma referência na tabela.

  • A fonte de dados é um IQueryable<T>arquivo . Existem dois cenários:

    • Se o LINQ to SQL encontrar o subjacente Table<TEntity> do IQueryable<T>, a fonte permitirá a edição e a situação será a mesma do primeiro ponto.

    • Se o LINQ to SQL não conseguir encontrar o subjacente Table<TEntity>, a fonte não permitirá a edição (por exemplo, groupby). LINQ to SQL navega na consulta para preencher um genérico SortableBindingList, que é um simples BindingList<T> que implementa o recurso de classificação para entidades T para uma determinada propriedade.

Coleções Especializadas

Para muitos recursos descritos anteriormente neste documento, BindingList<T> foi especializado para algumas classes diferentes. Estas classes são genéricas SortableBindingList e genéricas DataBindingList. Ambos são declarados como internos.

SortableBindingList Genérico

Esta classe herda de BindingList<T>, e é uma versão classificável do BindingList<T>. A classificação é uma solução na memória e nunca entra em contato com o banco de dados em si. BindingList<T> implementa, IBindingList mas não suporta a classificação por padrão. No entanto, BindingList<T> implementa IBindingList com métodos de núcleo virtual. Você pode facilmente substituir esses métodos. Substituições genéricas SortableBindingListSupportsSortingCore, SortPropertyCore, SortDirectionCore, e ApplySortCore. ApplySortCore é chamado por ApplySort e classifica a lista de itens T para uma determinada propriedade.

Uma exceção é levantada se o imóvel não pertencer a T.

Para obter a classificação, o LINQ to SQL cria uma classe genérica SortableBindingList.PropertyComparer que herda do genérico IComparer.Compare e implementa um comparador padrão para um determinado tipo T, a PropertyDescriptore uma direção. Esta classe cria dinamicamente um Comparer de T onde T é o PropertyType do PropertyDescriptor. Em seguida, o comparador padrão é recuperado do genérico Comparerestático . Uma instância padrão é obtida usando reflexão.

Generic SortableBindingList também é a classe base para DataBindingList. O Generic SortableBindingList oferece dois métodos virtuais para suspender ou retomar itens: adicionar/remover rastreamento. Esses dois métodos podem ser usados para recursos básicos, como classificação, mas realmente serão implementados por classes superiores, como genéricos DataBindingList.

DataBindingList Genérico

Esta classe herda do genérico SortableBindingLIst. Generic DataBindingList mantém uma referência sobre o genérico Table subjacente do genérico IQueryable usado para o enchimento inicial da coleção. Generic DatabindingList adiciona rastreamento para adicionar/remover item à coleção substituindo InsertItem() e RemoveItem(). Ele também implementa o recurso abstrato de rastreamento de suspensão/retomada para tornar o rastreamento condicional. Esse recurso faz com que os genéricos DataBindingList aproveitem todo o uso polimórfico do recurso de rastreamento das classes pai.

Vinculação a EntitySets

A vinculação a EntitySet é um caso especial porque EntitySet já é uma coleção que implementa IBindingList. O LINQ to SQL adiciona suporte a classificação e cancelamento (ICancelAddNew). Uma EntitySet classe usa uma lista interna para armazenar entidades. Esta lista é uma coleção de baixo nível baseada em uma matriz genérica, a classe genérica ItemList .

Adicionando um recurso de classificação

As matrizes oferecem um método de classificação (Array.Sort()) que você pode ser usado com um Comparer de T. LINQ to SQL usa a classe genérica SortableBindingList.PropertyComparer descrita anteriormente neste tópico para obtê-la Comparer para a propriedade e a direção a ser classificada. Um ApplySort método é adicionado ao genérico ItemList para chamar esse recurso.

EntitySet Ao lado, agora você tem que declarar suporte de classificação:

Quando você usa um System.Windows.Forms.BindingSource e vincula um TEntity EntitySet<ao System.Windows.Forms.BindingSource.DataSource, você deve chamar EntitySet<TEntity>.> GetNewBindingList para atualizar BindingSource.List.

Se você usar um System.Windows.Forms.BindingSource e definir a propriedade BindingSource.DataMember e definir BindingSource.DataSource para uma classe que tenha uma propriedade nomeada no BindingSource.DataMember que expõe a TEntity EntitySet<, não será necessário chamar EntitySet<TEntity>>. GetNewBindingList para atualizar o BindingSource.List, mas você perde a capacidade de classificação.

Colocação em cache

As consultas LINQ to SQL implementam GetListo . Quando a classe BindingSource do Windows Forms atende a essa interface, ela chama GetList() três vezes para uma única conexão. Para contornar essa situação, o LINQ to SQL implementa um cache por instância para armazenar e sempre retornar a mesma coleção gerada.

Cancelamento

IBindingList Define um AddNew método que é usado por controles para criar um novo item de uma coleção acoplada. O DataGridView controle mostra esse recurso muito bem quando a última linha visível contém uma estrela em seu cabeçalho. A estrela mostra que você pode adicionar um novo item.

Além desse recurso, uma coleção também pode implementar ICancelAddNewo . Esse recurso permite que os controles cancelem ou validem se o novo item editado foi validado ou não.

ICancelAddNew é implementado em todas as coleções vinculadas a dados LINQ to SQL (genéricas SortableBindingList e genéricas EntitySet). Em ambas as implementações, o código executa da seguinte maneira:

  • Permite que os itens sejam inseridos e, em seguida, removidos da coleção.

  • Não controla as alterações, desde que a interface do usuário não confirme a edição.

  • Não controla alterações desde que a edição seja cancelada (CancelNew).

  • Permite acompanhar quando a edição é confirmada (EndNew).

  • Permite que a coleção se comporte normalmente se o novo item não vier de AddNew.

Resolução de Problemas

Esta seção destaca vários itens que podem ajudar a solucionar problemas de seus aplicativos de vinculação de dados LINQ to SQL.

  • Você deve usar propriedades; utilizar apenas campos não é suficiente. Os Windows Forms exigem esse uso.

  • Por padrão, image, varbinarye timestamp os tipos de banco de dados são mapeados para a matriz de bytes. Como ToString() não há suporte nesse cenário, esses objetos não podem ser exibidos.

  • Um membro de classe mapeado para uma chave primária tem um setter, mas o LINQ to SQL não oferece suporte à alteração de identidade do objeto. Portanto, a chave primária/exclusiva usada no mapeamento não pode ser atualizada no banco de dados. Uma alteração na grade causa uma exceção quando você chama SubmitChanges.

  • Se uma entidade estiver vinculada em duas grades separadas (por exemplo, uma mestre e outro detalhe), uma Delete na grade mestra não será propagada para a grade de detalhes.

Consulte também