Partilhar via


Trabalhando com colunas computadas (VB)

por Scott Mitchell

Descarregar PDF

Ao criar uma tabela de banco de dados, o Microsoft SQL Server permite definir uma coluna computada cujo valor é calculado a partir de uma expressão que geralmente faz referência a outros valores no mesmo registro de banco de dados. Esses valores são somente leitura no banco de dados, o que requer considerações especiais quando se trabalha com TableAdapters. Neste tutorial, aprendemos como enfrentar os desafios colocados pelas colunas computadas.

Introdução

O Microsoft SQL Server permite colunas computadas, que são colunas cujos valores são calculados a partir de uma expressão que geralmente faz referência aos valores de outras colunas na mesma tabela. Por exemplo, um modelo de dados de controle de tempo pode ter uma tabela nomeada ServiceLog com colunas incluindo ServicePerformed, EmployeeID, Rate, e Duration, entre outras. Embora o valor devido por item de serviço (sendo a taxa multiplicada pela duração) possa ser calculado por meio de uma página da Web ou outra interface programática, pode ser útil incluir uma coluna na ServiceLog tabela chamada AmountDue que relatou essas informações. Esta coluna poderia ser criada como uma coluna normal, mas precisaria ser atualizada sempre que os valores da Rate coluna ou Duration fossem alterados. Uma abordagem melhor seria tornar a AmountDue coluna uma coluna computada usando a expressão Rate * Duration. Isso faria com que o SQL Server calculasse automaticamente o valor da AmountDue coluna sempre que ela fosse referenciada em uma consulta.

Como o valor de uma coluna calculada é determinado por uma expressão, essas colunas são somente leitura e, portanto, não podem ter valores atribuídos a elas em instruções INSERT ou UPDATE. No entanto, quando as colunas computadas fazem parte da consulta principal para um TableAdapter que usa instruções SQL ad-hoc, elas são automaticamente incluídas nas instruções geradas automaticamente INSERT e UPDATE. Consequentemente, as consultas INSERT e UPDATE e as propriedades InsertCommand e UpdateCommand do TableAdapter devem ser atualizadas para remover referências a quaisquer colunas computadas.

Um desafio de usar colunas computadas com um TableAdapter que utiliza instruções SQL ad-hoc é que as consultas do TableAdapter como INSERT e UPDATE são regeneradas automaticamente sempre que o assistente de Configuração do TableAdapter é concluído. Portanto, as colunas computadas removidas manualmente das consultas INSERT e UPDATE reaparecerão se o assistente for executado novamente. Embora os TableAdapters que usam procedimentos armazenados não sofram dessa fragilidade, eles têm suas próprias peculiaridades que abordaremos na Etapa 3.

Neste tutorial, adicionaremos uma coluna computada Suppliers à tabela no banco de dados Northwind e, em seguida, criaremos um TableAdapter correspondente para trabalhar com essa tabela e sua coluna calculada. Vamos ter o nosso TableAdapter a usar procedimentos armazenados em vez de instruções SQL pontuais para que as nossas personalizações não sejam perdidas quando usado o assistente de configuração do TableAdapter.

Vamos começar!

Etapa 1: Adicionando uma coluna computadaSuppliersà tabela

O banco de dados Northwind não tem colunas computadas, então precisaremos adicionar uma. Para este tutorial, permita que s adicione uma coluna computada Suppliers à tabela chamada FullContactName que retorna o nome, o título e a empresa para a qual o contato trabalha no seguinte formato: ContactName (ContactTitle, CompanyName). Esta coluna computada pode ser usada em relatórios ao exibir informações sobre fornecedores.

Comece por abrir a definição da Suppliers tabela ao clicar com o botão direito do Suppliers mouse na tabela no Explorador de Servidor e escolher Abrir Definição de Tabela no menu de contexto. Isso exibirá as colunas da tabela e suas propriedades, como o tipo de dados, se permitem NULL s e assim por diante. Para adicionar uma coluna calculada, comece digitando o nome da coluna na definição da tabela. Em seguida, insira sua expressão na caixa de texto (Fórmula) na seção Especificação de coluna computada na janela Propriedades da coluna (consulte a Figura 1). Nomeie a coluna FullContactName computada e use a seguinte expressão:

ContactName + ' (' + CASE WHEN ContactTitle IS NOT NULL THEN 
    ContactTitle + ', ' ELSE '' END + CompanyName + ')'

Observe que as cadeias de caracteres podem ser concatenadas em SQL usando o + operador . A CASE instrução pode ser usada como uma condicional em uma linguagem de programação tradicional. Na expressão acima, a afirmação CASE pode ser lida como: Se ContactTitle não é NULL, então produza o valor ContactTitle concatenado com uma vírgula, caso contrário, não emitir nada. Para obter mais informações sobre a CASE utilidade da instrução, consulte Instruções SQLCASE.

Observação

Em vez de usar uma CASE declaração aqui, poderíamos ter usado ISNULL(ContactTitle, '')alternativamente . ISNULL(checkExpression, replacementValue) retorna checkExpression se não for nulo; caso contrário, retorna replacementValue. Embora ISNULL ou CASE sejam eficazes neste caso, há cenários mais complexos em que a flexibilidade da instrução CASE não pode ser correspondida pela ISNULL.

Depois de adicionar essa coluna computada, sua tela deve se parecer com a captura de tela na Figura 1.

Adicionar uma coluna computada chamada FullContactName à tabela Fornecedores

Figura 1: Adicionar uma coluna computada nomeada FullContactName à tabela (Suppliers imagem em tamanho real)

Depois de nomear a coluna computada e inserir sua expressão, salve as alterações na tabela clicando no ícone Salvar na barra de ferramentas, pressionando Ctrl+S ou indo para o menu Arquivo e escolhendo Salvar Suppliers.

Salvar a tabela deve atualizar o Gerenciador de Servidores, incluindo a coluna recém-adicionada na lista de colunas da tabela Suppliers. Além disso, a expressão inserida na caixa de texto (Fórmula) será automaticamente ajustada a uma expressão equivalente que retira espaços em branco desnecessários, envolve nomes de colunas com colchetes ([]) e inclui parênteses para mostrar mais explicitamente a ordem das operações:

(((([ContactName]+' (')+case when [ContactTitle] IS NOT NULL 
    then [ContactTitle]+', ' else '' end)+[CompanyName])+')')

Para obter mais informações sobre colunas computadas no Microsoft SQL Server, consulte a documentação técnica. Confira também Como: Especificar colunas computadas para obter um passo a passo sobre a criação de colunas computadas.

Observação

Por padrão, as colunas computadas não são fisicamente armazenadas na tabela, mas são recalculadas cada vez que são referenciadas em uma consulta. No entanto, marcando a caixa de seleção É persistente, você pode instruir o SQL Server a armazenar fisicamente a coluna computada na tabela. Isso permite que um índice seja criado na coluna calculada, o que pode melhorar o desempenho de consultas que usam o valor da coluna computada em suas WHERE cláusulas. Consulte Criando índices em colunas computadas para obter mais informações.

Etapa 2: Visualizando os valores computados da coluna

Antes de começarmos a trabalhar na Camada de Acesso a Dados, vamos dedicar um minuto para visualizar os valores FullContactName. No Gerenciador de Servidores, clique com o botão direito do mouse no nome da Suppliers tabela e escolha Nova Consulta no menu de contexto. Isso abrirá uma janela Consulta que nos solicitará a escolha de quais tabelas incluir na consulta. Adicione a Suppliers tabela e clique em Fechar. Em seguida, verifique as colunas CompanyName, ContactName, ContactTitle e FullContactName da tabela Fornecedores. Por fim, clique no ícone vermelho do ponto de exclamação na Barra de Ferramentas para executar a consulta e exibir os resultados.

Como mostra a Figura 2, os resultados incluem FullContactName, que lista as CompanyNamecolunas , ContactNamee ContactTitle usando o formato ContactName (ContactTitle, CompanyName).

O FullContactName usa o formato ContactName (ContactTitle, CompanyName)

Figura 2: O FullContactName usa o formato ContactName (ContactTitle, CompanyName) (Clique para visualizar a imagem em tamanho real)

Etapa 3: Adicionando oSuppliersTableAdapterà camada de acesso a dados

Para trabalhar com as informações do fornecedor em nosso aplicativo, precisamos primeiro criar um TableAdapter e DataTable em nosso DAL. Idealmente, isso seria feito usando as mesmas etapas simples examinadas em tutoriais anteriores. No entanto, trabalhar com colunas calculadas introduz algumas complicações que merecem discussão.

Se você estiver usando um TableAdapter que usa instruções SQL ad-hoc, você pode simplesmente incluir a coluna computada na consulta principal do TableAdapter por meio do assistente de configuração do TableAdapter. Isso, no entanto, irá gerar automaticamente instruções INSERT e UPDATE que incluem a coluna computada. Se o utilizador tentar executar um desses métodos, um SqlException com a mensagem A coluna ColumnName não pode ser modificada porque é uma coluna calculada ou é o resultado de um operador UNION será gerado. Embora a instrução INSERT e UPDATE possam ser ajustadas manualmente por meio das propriedades InsertCommand TableAdapter e UpdateCommand, essas personalizações serão perdidas sempre que o assistente de Configuração do TableAdapter for executado novamente.

Devido à fragilidade dos TableAdapters que usam instruções SQL ad-hoc, é recomendável usar procedimentos armazenados ao trabalhar com colunas computadas. Se estiver a usar procedimentos armazenados existentes, basta configurar o TableAdapter conforme discutido no tutorial Usando procedimentos armazenados existentes para os TableAdapters do conjunto de dados tipados. No entanto, se o assistente TableAdapter criar os procedimentos armazenados para você, é importante omitir inicialmente todas as colunas computadas da consulta principal. Se você incluir uma coluna computada na consulta principal, o assistente de Configuração do TableAdapter informará, após a conclusão, que não pode criar os procedimentos armazenados correspondentes. Em resumo, precisamos configurar inicialmente o TableAdapter usando uma consulta principal sem colunas computada e, em seguida, atualizar manualmente o procedimento armazenado correspondente e o TableAdapter s SelectCommand para incluir a coluna computada. Essa abordagem é semelhante à usada no tutorial Atualizando o TableAdapter to UseJOINs .

Para este tutorial, vamos adicionar um novo TableAdapter e fazê-lo criar automaticamente os procedimentos armazenados para nós. Consequentemente, precisaremos inicialmente omitir a FullContactName coluna computada da consulta principal.

Comece abrindo o NorthwindWithSprocs DataSet na ~/App_Code/DAL pasta. Clique com o botão direito do mouse no Designer e, no menu de contexto, escolha adicionar um novo TableAdapter. Isso iniciará o assistente de configuração do TableAdapter. Especifique o banco de dados para consultar dados (NORTHWNDConnectionString de Web.config) e clique em Avançar. Como ainda não criamos nenhum procedimento armazenado para consultar ou modificar a Suppliers tabela, selecione a opção Criar novos procedimentos armazenados para que o assistente os crie para nós e clique em Avançar.

Escolha a opção Criar novos procedimentos armazenados

Figura 3: Escolha a opção Create new stored procedures (Clique para visualizar a imagem em tamanho real)

A etapa subsequente nos solicita a pergunta principal. Insira a consulta a seguir, que retorna as SupplierIDcolunas , CompanyName, ContactNamee ContactTitle para cada fornecedor. Observe que esta consulta omite propositalmente a coluna computada (FullContactName); atualizaremos o procedimento armazenado correspondente para incluir esta coluna na Etapa 4.

SELECT SupplierID, CompanyName, ContactName, ContactTitle
FROM Suppliers

Depois de inserir a consulta principal e clicar em Avançar, o assistente nos permite nomear os quatro procedimentos armazenados que irá gerar. Denomine esses procedimentos armazenados Suppliers_Select, Suppliers_Insert, Suppliers_Update, e Suppliers_Delete, conforme ilustrado na Figura 4.

Personalizar os nomes dos procedimentos armazenados gerados automaticamente

Figura 4: Personalizar os nomes dos procedimentos armazenados gerados automaticamente (Clique para visualizar a imagem em tamanho real)

A próxima etapa do assistente nos permite nomear os métodos do TableAdapter e especificar os padrões usados para acessar e atualizar dados. Deixe todas as três caixas de seleção marcadas, mas renomeie o GetData método para GetSuppliers. Clique em Concluir para finalizar o assistente.

Renomeie o método GetData para GetSuppliers

Figura 5: Renomeie o método para GetData (GetSuppliers imagem em tamanho real)

Ao clicar em Concluir, o assistente criará os quatro procedimentos armazenados e adicionará o TableAdapter e o DataTable correspondente ao conjunto de dados tipado.

Etapa 4: Incluindo a coluna computada na consulta principal do TableAdapter

Agora precisamos atualizar o TableAdapter e o DataTable criados na Etapa 3 para incluir a FullContactName coluna computada. Isto envolve duas etapas:

  1. Atualizando o Suppliers_Select procedimento armazenado para retornar a coluna computada FullContactName e
  2. Atualização da DataTable para incluir uma coluna correspondente FullContactName.

Comece navegando até o Gerenciador de Servidores e detalhando a pasta Procedimentos Armazenados. Abra o Suppliers_Select procedimento armazenado e atualize a SELECT consulta para incluir a FullContactName coluna computada:

SELECT SupplierID, CompanyName, ContactName, ContactTitle, FullContactName
FROM Suppliers

Salve as alterações no procedimento armazenado clicando no ícone Salvar na Barra de Ferramentas, pressionando Ctrl+S ou escolhendo a opção Salvar Suppliers_Select no menu Arquivo.

Em seguida, retorne ao DataSet Designer, clique com o botão direito do mouse no SuppliersTableAdapter e escolha Configurar no menu de contexto. Observe que a Suppliers_Select coluna agora inclui a FullContactName coluna em sua coleção Data Columns.

Execute o Assistente de Configuração do TableAdapter para atualizar as colunas do DataTable

Figura 6: Execute o Assistente de Configuração do TableAdapter para atualizar as colunas do DataTable (Clique para visualizar a imagem em tamanho real)

Clique em Concluir para finalizar o assistente. Isso adicionará automaticamente uma coluna correspondente ao SuppliersDataTable. O assistente TableAdapter é inteligente o suficiente para detetar que a coluna FullContactName é uma coluna computada e, portanto, de apenas leitura. Consequentemente, ele define a propriedade ReadOnlyda coluna como true . Para verificar isto, selecione a coluna do SuppliersDataTable e, em seguida, vá para a janela Propriedades (consulte a Figura 7). Observe que a FullContactName coluna e as DataType e MaxLength propriedades também são definidas de acordo.

A coluna FullContactName está marcada como somente leitura

Figura 7: A FullContactName coluna está marcada como Read-Only (Clique para visualizar a imagem em tamanho real)

Etapa 5: Adicionando umGetSupplierBySupplierIDmétodo ao TableAdapter

Para este tutorial, criaremos uma página de ASP.NET que exibe os fornecedores em uma grade atualizável. Em tutoriais anteriores, atualizamos um único registro da Business Logic Layer recuperando esse registro específico da DAL como uma DataTable fortemente tipada, atualizando suas propriedades e, em seguida, enviando a DataTable atualizada de volta para a DAL para propagar as alterações no banco de dados. Para realizar esta primeira etapa - recuperar o registro que está sendo atualizado do DAL - precisamos primeiro adicionar um GetSupplierBySupplierID(supplierID) método ao DAL.

Clique com o botão direito do rato no elemento SuppliersTableAdapter no DataSet Design e escolha a opção Adicionar consulta no menu de contexto. Como fizemos na Etapa 3, deixe o assistente gerar um novo procedimento armazenado para nós selecionando a opção Create new stored procedure (consulte a Figura 3 para obter uma captura de tela desta etapa do assistente). Como esse método retornará um registro com várias colunas, indique que queremos usar uma consulta SQL que é um SELECT que retorna linhas e clique em Avançar.

Escolha a opção SELECT que retorna linhas

Figura 8: Escolha a opção SELECT que retorna linhas (Clique para visualizar a imagem em tamanho real)

A etapa subsequente nos solicita que a consulta seja usada para esse método. Insira o seguinte, que retorna os mesmos campos de dados da consulta principal, mas para um fornecedor específico.

SELECT SupplierID, CompanyName, ContactName, ContactTitle, FullContactName
FROM Suppliers
WHERE SupplierID = @SupplierID

A próxima tela nos pede para nomear o procedimento armazenado que será gerado automaticamente. Nomeie este procedimento Suppliers_SelectBySupplierID armazenado e clique em Avançar.

Nomeie o procedimento armazenado Suppliers_SelectBySupplierID

Figura 9: Nomeie o procedimento Suppliers_SelectBySupplierID armazenado (Clique para visualizar a imagem em tamanho real)

Por fim, o assistente nos solicita os padrões de acesso a dados e nomes de método a serem usados para o TableAdapter. Deixe ambas as caixas de seleção marcadas, mas renomeie os FillBy métodos e GetDataBy para FillBySupplierID e GetSupplierBySupplierID, respectivamente.

Nomeie os métodos TableAdapter FillBySupplierID e GetSupplierBySupplierID

Figura 10: Nomeie os métodos FillBySupplierID TableAdapter e GetSupplierBySupplierID (Clique para visualizar a imagem em tamanho real)

Clique em Concluir para finalizar o assistente.

Etapa 6: Criando a camada de lógica de negócios

Antes de criarmos uma página de ASP.NET que usa a coluna computada criada na Etapa 1, primeiro precisamos adicionar os métodos correspondentes na BLL. Nossa página ASP.NET, que criaremos na Etapa 7, permitirá que os usuários visualizem e editem fornecedores. Portanto, precisamos que nossa BLL forneça, no mínimo, um método para obter todos os fornecedores e outro para atualizar um determinado fornecedor.

Crie um novo arquivo de classe nomeado SuppliersBLLWithSprocs na ~/App_Code/BLL pasta e adicione o seguinte código:

Imports NorthwindWithSprocsTableAdapters
<System.ComponentModel.DataObject()> _
Public Class SuppliersBLLWithSprocs
    Private _suppliersAdapter As SuppliersTableAdapter = Nothing
    Protected ReadOnly Property Adapter() As SuppliersTableAdapter
        Get
            If _suppliersAdapter Is Nothing Then
                _suppliersAdapter = New SuppliersTableAdapter()
            End If
            Return _suppliersAdapter
        End Get
    End Property
    <System.ComponentModel.DataObjectMethodAttribute _
        (System.ComponentModel.DataObjectMethodType.Select, True)> _
    Public Function GetSuppliers() As NorthwindWithSprocs.SuppliersDataTable
        Return Adapter.GetSuppliers()
    End Function
    <System.ComponentModel.DataObjectMethodAttribute _
        (System.ComponentModel.DataObjectMethodType.Update, True)> _
    Public Function UpdateSupplier(companyName As String, contactName As String, _
        contactTitle As String, supplierID As Integer) As Boolean
        Dim suppliers As NorthwindWithSprocs.SuppliersDataTable = _
            Adapter.GetSupplierBySupplierID(supplierID)
        If suppliers.Count = 0 Then
            ' no matching record found, return false
            Return False
        End If
        Dim supplier As NorthwindWithSprocs.SuppliersRow = suppliers(0)
        supplier.CompanyName = companyName
        If contactName Is Nothing Then 
            supplier.SetContactNameNull() 
        Else 
            supplier.ContactName = contactName
        End If
        If contactTitle Is Nothing Then 
            supplier.SetContactTitleNull() 
        Else 
            supplier.ContactTitle = contactTitle
        End If
        ' Update the product record
        Dim rowsAffected As Integer = Adapter.Update(supplier)
        ' Return true if precisely one row was updated, otherwise false
        Return rowsAffected = 1
    End Function
End Class

Como as outras classes BLL, SuppliersBLLWithSprocs tem uma ProtectedAdapter propriedade que retorna uma instância da SuppliersTableAdapter classe junto com dois Public métodos: GetSuppliers e UpdateSupplier. O GetSuppliers método chama e retorna o SuppliersDataTable retornado pelo método correspondente GetSupplier na camada de acesso a dados. O método UpdateSupplier recupera informações sobre o fornecedor específico que está a ser atualizado por meio de uma chamada para o método do DAL GetSupplierBySupplierID(supplierID). Em seguida, ele atualiza as propriedades CategoryName, ContactName e ContactTitle e confirma essas alterações no banco de dados chamando o método Update da Camada de Acesso a Dados, passando o objeto modificado SuppliersRow.

Observação

Com exceção de SupplierID e CompanyName, todas as colunas na tabela Fornecedores permitem valores NULL. Portanto, se os parâmetros fornecidos contactName ou contactTitle são Nothing, precisamos definir as propriedades ContactName e ContactTitle correspondentes para um valor de banco de dados NULL usando, respetivamente, os métodos SetContactNameNull e SetContactTitleNull.

Etapa 7: Trabalhando com a coluna computada da camada de apresentação

Com a coluna computada adicionada à Suppliers tabela e o DAL e BLL atualizados de acordo, estamos prontos para construir uma página ASP.NET que funcione com a FullContactName coluna computada. Comece por abrir a página ComputedColumns.aspx na pasta AdvancedDAL e arraste um GridView do Toolbox para o Designer. Defina a propriedade do GridView ID como Suppliers e, a partir da sua marca inteligente, vincule-a a um novo ObjectDataSource chamado SuppliersDataSource. Configure o ObjectDataSource para usar a SuppliersBLLWithSprocs classe que adicionamos novamente na Etapa 6 e clique em Avançar.

Configurar o ObjectDataSource para usar a classe SuppliersBLLWithSprocs

Figura 11: Configurar o ObjectDataSource para usar a classe (SuppliersBLLWithSprocs imagem em tamanho real)

Existem apenas dois métodos definidos na SuppliersBLLWithSprocs classe: GetSuppliers e UpdateSupplier. Verifique se esses dois métodos estão especificados nas guias SELECT e UPDATE, respectivamente, e clique em Concluir para concluir a configuração do ObjectDataSource.

Após a conclusão do assistente de Configuração da Fonte de Dados, o Visual Studio adicionará um BoundField para cada um dos campos de dados retornados. Remova o SupplierID BoundField e altere as HeaderText propriedades de CompanyName, ContactName, ContactTitlee FullContactName BoundFields para Company, Contact Name, Title e Full Contact Name, respectivamente. Na etiqueta inteligente, marque a caixa de seleção "Habilitar edição" para ativar as capacidades de edição integradas do GridView.

Além de adicionar BoundFields ao GridView, a conclusão do Assistente de Fonte de Dados também faz com que o Visual Studio defina a propriedade ObjectDataSource como OldValuesParameterFormatString original_{0}. Reverta essa configuração de volta para seu valor padrão, {0} .

Depois de fazer essas edições no GridView e ObjectDataSource, sua marcação declarativa deve ser semelhante à seguinte:

<asp:GridView ID="Suppliers" runat="server" AutoGenerateColumns="False" 
    DataKeyNames="SupplierID" DataSourceID="SuppliersDataSource">
    <Columns>
        <asp:CommandField ShowEditButton="True" />
        <asp:BoundField DataField="CompanyName" 
            HeaderText="Company" 
            SortExpression="CompanyName" />
        <asp:BoundField DataField="ContactName" 
            HeaderText="Contact Name" 
            SortExpression="ContactName" />
        <asp:BoundField DataField="ContactTitle" 
            HeaderText="Title" 
            SortExpression="ContactTitle" />
        <asp:BoundField DataField="FullContactName" 
            HeaderText="Full Contact Name"
            SortExpression="FullContactName" 
            ReadOnly="True" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="SuppliersDataSource" runat="server"
    SelectMethod="GetSuppliers" TypeName="SuppliersBLLWithSprocs" 
        UpdateMethod="UpdateSupplier">
    <UpdateParameters>
        <asp:Parameter Name="companyName" Type="String" />
        <asp:Parameter Name="contactName" Type="String" />
        <asp:Parameter Name="contactTitle" Type="String" />
        <asp:Parameter Name="supplierID" Type="Int32" />
    </UpdateParameters>
</asp:ObjectDataSource>

Em seguida, visite esta página através de um navegador. Como mostra a Figura 12, cada fornecedor é listado em uma grade que inclui a FullContactName coluna, cujo valor é simplesmente a concatenação das outras três colunas formatadas como ContactName (ContactTitle, CompanyName) .

Cada fornecedor está listada na grelha

Figura 12: Cada fornecedor está listado na grade (Clique para visualizar a imagem em tamanho real)

Clicar no botão Editar para um determinado fornecedor causa um postback e faz com que essa linha seja renderizada na sua interface de edição (consulte a Figura 13). As três primeiras colunas são renderizadas em sua interface de edição padrão - um controle TextBox cuja Text propriedade é definida como o valor do campo de dados. A FullContactName coluna, no entanto, permanece como texto. Quando os BoundFields foram adicionados ao GridView na conclusão do assistente de Configuração da Fonte de Dados, a propriedade FullContactName de BoundField ReadOnly foi definida como True porque a coluna FullContactName correspondente no SuppliersDataTable tem sua propriedade ReadOnly definida como True. Conforme observado na etapa 4, a FullContactName propriedade s ReadOnly foi definida como True porque o TableAdapter detetou que a coluna era uma coluna calculada.

A coluna FullContactName não é editável

Figura 13: A FullContactName coluna não é editável (Clique para visualizar a imagem em tamanho real)

Vá em frente e atualize o valor de uma ou mais das colunas editáveis e clique em Atualizar. Observe como o FullContactName valor s é atualizado automaticamente para refletir a alteração.

Observação

O GridView atualmente usa BoundFields para os campos editáveis, resultando na interface de edição padrão. Como o CompanyName campo é obrigatório, ele deve ser convertido em um TemplateField que inclui um RequiredFieldValidator. Deixo isto como um exercício para o leitor interessado. Consulte o tutorial Adicionando controles de validação ao tutorial Editando e inserindo interfaces para obter instruções passo a passo sobre como converter um BoundField em um TemplateField e adicionar controles de validação.

Resumo

Ao definir o esquema para uma tabela, o Microsoft SQL Server permite a inclusão de colunas computadas. Estas são colunas cujos valores são calculados a partir de uma expressão que normalmente faz referência aos valores de outras colunas no mesmo registo. Como os valores para colunas calculadas são baseados numa expressão, eles são de apenas leitura e não podem ser atribuídos a um valor numa instrução INSERT ou UPDATE. Isso introduz desafios ao utilizar uma coluna calculada na consulta principal de um TableAdapter que tenta gerar as instruções INSERT, UPDATE e DELETE correspondentes automaticamente.

Neste tutorial, discutimos técnicas para contornar os desafios colocados pelas colunas computadas. Em particular, usamos procedimentos armazenados em nosso TableAdapter para superar a fragilidade inerente aos TableAdapters que usam instruções SQL ad-hoc. Ao fazer com que o assistente TableAdapter crie novos procedimentos armazenados, é importante que a consulta principal inicialmente omita quaisquer colunas computadas porque sua presença impede que os procedimentos armazenados de modificação de dados sejam gerados. Depois de o TableAdapter ter sido inicialmente configurado, o seu procedimento de armazenamento SelectCommand pode ser reconfigurado para incluir quaisquer colunas calculadas.

Feliz Programação!

Sobre o Autor

Scott Mitchell, autor de sete livros sobre ASP/ASP.NET e fundador da 4GuysFromRolla.com, trabalha com tecnologias Web da Microsoft desde 1998. Scott trabalha como consultor, formador e escritor independente. Seu último livro é Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Ele pode ser contatado em mitchell@4GuysFromRolla.com.

Um agradecimento especial a

Esta série de tutoriais foi revisada por muitos revisores úteis. Os principais revisores deste tutorial foram Hilton Geisenow e Teresa Murphy. Interessado em rever meus próximos artigos do MSDN? Se for o caso, envie-me uma mensagem para mitchell@4GuysFromRolla.com.