Compartilhar via


Trabalhar com colunas computadas (C#)

por Scott Mitchell

Baixar PDF

Ao criar uma tabela de banco de dados, o Microsoft SQL Server permite que você defina 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 ao trabalhar com TableAdapters. Neste tutorial, aprendemos como enfrentar os desafios impostos 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 com colunas que ServiceLog incluem ServicePerformed, EmployeeID, , Ratee 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. Essa coluna pode 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 coluna sempre que ele fosse referenciado AmountDue em uma consulta.

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

Um desafio de usar colunas computadas com um TableAdapter que usa instruções SQL ad hoc é que o TableAdapter s e UPDATE as INSERT consultas são regenerados automaticamente sempre que o assistente de Configuração do TableAdapter é concluído. Portanto, as colunas computadas removidas manualmente das INSERT consultas 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 computada. Faremos com que nosso TableAdapter use procedimentos armazenados em vez de instruções SQL ad hoc para que nossas personalizações não sejam perdidas quando o assistente de configuração do TableAdapter for usado.

Vamos começar!

Etapa 1: Adicionando uma coluna computada àSupplierstabela

O banco de dados Northwind não possui colunas computadas, portanto, precisaremos adicionar uma nós mesmos. Para este tutorial, vamos adicionar uma coluna computada Suppliers à tabela chamada FullContactName que retorna o nome do contato, o cargo e a empresa para a qual trabalham no seguinte formato: ContactName (ContactTitle, CompanyName). Essa coluna computada pode ser usada em relatórios ao exibir informações sobre fornecedores.

Comece abrindo a definição de tabela clicando com o Suppliers botão direito do Suppliers mouse na tabela no Gerenciador de Servidores e escolhendo Abrir Definição de Tabela no menu de contexto. Isso exibirá as colunas da tabela e suas propriedades, como o tipo de dados, se elas permitem NULL s e assim por diante. Para adicionar uma coluna computada, 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 CASE instrução pode ser lida como: Se ContactTitle não NULL for, então produza o ContactTitle valor concatenado com uma vírgula, caso contrário, não emita 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 NULL, caso contrário, retornará replacementValue. Embora um ou ISNULL CASE funcione neste caso, há cenários mais intrincados em que a CASE flexibilidade da instrução não pode ser correspondida por 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 (clique para exibir a 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 acessando o menu Arquivo e escolhendo Salvar Suppliers.

Salvar a tabela deve atualizar o Gerenciador de Servidores, incluindo a coluna recém-adicionada na Suppliers lista de colunas da tabela. Além disso, a expressão inserida na caixa de texto (Fórmula) será ajustada automaticamente para uma expressão equivalente que remove espaços em branco desnecessários, coloca os nomes das colunas entre 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 o Como especificar colunas computadas para obter um passo a passo da criação de colunas computadas.

Observação

Por padrão, as colunas computadas não são armazenadas fisicamente na tabela, mas são recalculadas sempre 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 computada, 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: Exibindo os valores da coluna computada

Antes de começarmos a trabalhar na Camada de Acesso a Dados, vamos dedicar um minuto para exibir os FullContactName valores. 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 de consulta que nos solicita a escolha de quais tabelas incluir na consulta. Adicione a Suppliers tabela e clique em Fechar. Em seguida, verifique as CompanyNamecolunas , ContactName, ContactTitlee FullContactName e na tabela Fornecedores. Por fim, clique no ícone de ponto de exclamação vermelho 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 , ContactName, e ContactTitle usando o formato ldquo;ContactName (ContactTitle, CompanyName) .

O FullContactName usa o formato ContactName (ContactTitle, CompanyName)

Figura 2: O FullContactName usa o formato ContactName (ContactTitle, CompanyName) (clique para exibir 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 computadas introduz algumas rugas que merecem discussão.

Se você estiver usando um TableAdapter que usa instruções SQL ad hoc, poderá simplesmente incluir a coluna computada na consulta principal do TableAdapter por meio do assistente de configuração do TableAdapter. Isso, no entanto, será gerado INSERT automaticamente e UPDATE instruções que incluem a coluna computada. Se você tentar executar um desses métodos, um SqlException com a mensagem A coluna ColumnName não pode ser modificada porque é uma coluna computada ou é o resultado de um operador UNION será lançado. Embora a INSERT instrução and UPDATE possa ser ajustada manualmente por meio do TableAdapter s InsertCommand e UpdateCommand propriedades, 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 você estiver usando procedimentos armazenados existentes, basta configurar o TableAdapter conforme discutido no tutorial Usando procedimentos armazenados existentes para o TableAdapters do Conjunto de Dados Tipado. No entanto, se você tiver o assistente TableAdapter para 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 coluna computada e, em seguida, atualizar manualmente o procedimento armazenado correspondente e o TableAdapter para SelectCommand incluir a coluna computada. Essa abordagem é semelhante à usada no tutorial Atualizando o TableAdapter para usar .JOIN

Para este tutorial, vamos adicionar um novo TableAdapter e fazer com que ele crie automaticamente os procedimentos armazenados para nós. Consequentemente, precisaremos omitir inicialmente 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 do qual 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 Criar novos procedimentos armazenados (clique para exibir a imagem em tamanho real)

A etapa subsequente nos solicita a consulta principal. Insira a consulta a seguir, que retorna as SupplierIDcolunas , CompanyName, ContactNamee ContactTitle para cada fornecedor. Observe que essa consulta omite propositalmente a coluna computada (FullContactName); atualizaremos o procedimento armazenado correspondente para incluir essa 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 ele irá gerar. Nomeie esses procedimentos Suppliers_Selectarmazenados , Suppliers_Insert, Suppliers_Updatee Suppliers_Delete, como ilustra a Figura 4.

Personalizar os nomes dos procedimentos armazenados gerados automaticamente

Figura 4: Personalizar os nomes dos procedimentos armazenados gerados automaticamente (clique para exibir 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 concluir o assistente.

Renomeie o método GetData para GetSuppliers

Figura 5: Renomear o GetData método para GetSuppliers (clique para exibir a 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. Isso envolve duas etapas:

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

Comece navegando até o Gerenciador de Servidores e fazendo uma busca detalhada na 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 SuppliersTableAdaptermouse no e escolha Configurar no menu de contexto. Observe que a Suppliers_Select coluna agora inclui a FullContactName coluna em sua coleção de Colunas de Dados.

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

Figura 6: Executar o Assistente de Configuração do TableAdapter para atualizar as colunas do DataTable (clique para exibir a imagem em tamanho completo)

Clique em Concluir para concluir o assistente. Isso adicionará automaticamente uma coluna correspondente ao SuppliersDataTablearquivo . O assistente TableAdapter é inteligente o suficiente para detectar que a FullContactName coluna é uma coluna computada e, portanto, somente leitura. Consequentemente, ele define a propriedade da ReadOnly coluna como true. Para verificar isso, selecione a coluna no SuppliersDataTable e vá para a janela Properties (consulte a Figura 7). Observe que a coluna s DataType e MaxLength as FullContactName propriedades também são definidas adequadamente.

A coluna FullContactName é marcada como somente leitura

Figura 7: A FullContactName coluna está marcada como somente leitura (clique para exibir a imagem em tamanho real)

Etapa 5: Adicionando umGetSupplierBySupplierIDmétodo ao TableAdapter

Para este tutorial, criaremos uma página ASP.NET que exibe os fornecedores em uma grade atualizável. Em tutoriais anteriores, atualizamos um único registro da Camada Lógica de Negócios 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 para o banco de dados. Para realizar essa primeira etapa - recuperar o registro que está sendo atualizado da DAL - precisamos primeiro adicionar um GetSupplierBySupplierID(supplierID) método à DAL.

Clique com o botão direito do mouse no Design do SuppliersTableAdapter Conjunto de Dados 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 Criar novo procedimento armazenado (consulte a Figura 3 para obter uma captura de tela dessa etapa do assistente). Como esse método retornará um registro com várias colunas, indique que queremos usar uma consulta SQL que seja 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 exibir a imagem em tamanho real)

A etapa subsequente nos solicita a consulta a ser usada para esse método. Insira o seguinte, que retorna os mesmos campos de dados que a 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 esse procedimento Suppliers_SelectBySupplierID armazenado e clique em Avançar.

Nomeie o procedimento armazenado Suppliers_SelectBySupplierID

Figura 9: Nomear o procedimento Suppliers_SelectBySupplierID armazenado (clique para exibir a imagem em tamanho real)

Por fim, o assistente nos solicita os padrões de acesso a dados e os nomes de método a serem usados para o TableAdapter. Deixe as duas 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 exibir a imagem em tamanho real)

Clique em Concluir para concluir o assistente.

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

Antes de criarmos uma página 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:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using NorthwindWithSprocsTableAdapters;
[System.ComponentModel.DataObject]
public class SuppliersBLLWithSprocs
{
    private SuppliersTableAdapter _suppliersAdapter = null;
    protected SuppliersTableAdapter Adapter
    {
        get
        {
            if (_suppliersAdapter == null)
                _suppliersAdapter = new SuppliersTableAdapter();
            return _suppliersAdapter;
        }
    }
    [System.ComponentModel.DataObjectMethodAttribute
        (System.ComponentModel.DataObjectMethodType.Select, true)]
    public NorthwindWithSprocs.SuppliersDataTable GetSuppliers()
    {
        return Adapter.GetSuppliers();
    }
    [System.ComponentModel.DataObjectMethodAttribute
        (System.ComponentModel.DataObjectMethodType.Update, true)]
    public bool UpdateSupplier(string companyName, string contactName, 
        string contactTitle, int supplierID)
    {
        NorthwindWithSprocs.SuppliersDataTable suppliers = 
            Adapter.GetSupplierBySupplierID(supplierID);
        if (suppliers.Count == 0)
            // no matching record found, return false
            return false;
        NorthwindWithSprocs.SuppliersRow supplier = suppliers[0];
        supplier.CompanyName = companyName;
        if (contactName == null) 
            supplier.SetContactNameNull(); 
        else 
            supplier.ContactName = contactName;
        if (contactTitle == null) 
            supplier.SetContactTitleNull(); 
        else 
            supplier.ContactTitle = contactTitle;
        // Update the product record
        int rowsAffected = Adapter.Update(supplier);
        // Return true if precisely one row was updated, otherwise false
        return rowsAffected == 1;
    }
}

Como as outras classes BLL, SuppliersBLLWithSprocs tem uma protected Adapter 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 UpdateSupplier método recupera informações sobre o fornecedor específico que está sendo atualizado por meio de uma chamada para o método do GetSupplierBySupplierID(supplierID) DAL. Em seguida, ele atualiza as CategoryNamepropriedades , ContactNamee ContactTitle confirma essas alterações no banco de dados chamando o método da Camada de Update Acesso a Dados , passando o objeto modificado SuppliersRow .

Observação

Exceto para SupplierID e CompanyName, todas as colunas na tabela Fornecedores permitem NULL valores. Portanto, se os parâmetros ou contactTitle passados contactName foremnull, precisamos definir as propriedades and ContactTitle correspondentes ContactName para um NULL valor de banco de dados usando os SetContactNameNull métodos andSetContactTitleNull, respectivamente.

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

Com a coluna computada adicionada à Suppliers tabela e a DAL e a BLL atualizadas de acordo, estamos prontos para criar uma página ASP.NET que funcione com a FullContactName coluna computada. Comece abrindo a ComputedColumns.aspx AdvancedDAL página na pasta e arraste um GridView da Caixa de Ferramentas para o Designer. Defina a propriedade GridView ID como Suppliers e, em sua marca inteligente, associe-a a um novo ObjectDataSource chamado SuppliersDataSource. Configure o ObjectDataSource para usar a SuppliersBLLWithSprocs classe que adicionamos 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 (clique para exibir a SuppliersBLLWithSprocs imagem em tamanho real)

Existem apenas dois métodos definidos na SuppliersBLLWithSprocs classe: GetSuppliers e UpdateSupplier. Certifique-se de que esses dois métodos sejam especificados nas guias SELECT e UPDATE, respectivamente, e clique em Finish para concluir a configuração do ObjectDataSource.

Após a conclusão do assistente de Configuração de 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 , ContactName, ContactTitle, e FullContactName BoundFields para Empresa, Nome do Contato, Cargo e Nome Completo do CompanyNameContato, respectivamente. Na marca inteligente, marque a caixa de seleção Habilitar Edição para ativar os recursos de edição internos 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 do ObjectDataSource OldValuesParameterFormatString como original_{0}. Reverta essa configuração de volta ao seu valor padrão, {0} .

Depois de fazer essas edições no GridView e no 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 por meio 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 é listado na grade

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

Clicar no botão Edit para um fornecedor específico causa um postback e faz com que essa linha seja renderizada em 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 BoundField ReadOnly foi definida como true porque a SuppliersDataTable coluna correspondente FullContactName no tem sua ReadOnly propriedade definida como true.FullContactName Conforme observado na Etapa 4, a FullContactName propriedade s ReadOnly foi definida como true porque o TableAdapter detectou que a coluna era uma coluna computada.

A coluna FullContactName não é editável

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

Vá em frente e atualize o valor de uma ou mais 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 inclua um RequiredFieldValidator. Deixo isso como um exercício para o leitor interessado. Consulte o tutorial Adicionando controles de validação às interfaces de edição e inserção 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 de uma tabela, o Microsoft SQL Server permite a inclusão de colunas computadas. Essas são colunas cujos valores são calculados a partir de uma expressão que geralmente faz referência aos valores de outras colunas no mesmo registro. Como os valores das colunas computadas são baseados em uma expressão, eles são somente leitura e não podem ser atribuídos a um valor em uma INSERT instrução or UPDATE . Isso apresenta desafios ao usar uma coluna computada na consulta principal de um TableAdapter que tenta gerar automaticamente instruções , UPDATEe DELETE correspondentesINSERT.

Neste tutorial, discutimos técnicas para contornar os desafios impostos 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 omita inicialmente todas as colunas computadas, pois sua presença impede que os procedimentos armazenados de modificação de dados sejam gerados. Depois que o TableAdapter tiver sido configurado inicialmente, seu SelectCommand procedimento armazenado poderá ser reformulado para incluir todas as colunas computadas.

Boa programação!

Sobre o autor

Scott Mitchell, autor de sete livros ASP/ASP.NET e fundador da 4GuysFromRolla.com, trabalha com tecnologias da Web da Microsoft desde 1998. Scott trabalha como consultor, instrutor e escritor independente. Seu último livro é Sams Teach Yourself ASP.NET 2.0 em 24 horas. Ele pode ser contatado em mitchell@4GuysFromRolla.com. ou através de seu blog, que pode ser encontrado em http://ScottOnWriting.NET.

Agradecimentos especiais 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 revisar meus próximos artigos do MSDN? Em caso afirmativo, envie-me uma mensagem para mitchell@4GuysFromRolla.com.