Trabalhar com colunas computadas (C#)
por Scott Mitchell
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
, , 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. 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 àSuppliers
tabela
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.
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 CompanyName
colunas , ContactName
, ContactTitle
e 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 CompanyName
colunas , ContactName
, e ContactTitle
usando o formato ldquo;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.
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 SupplierID
colunas , CompanyName
, ContactName
e 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_Select
armazenados , Suppliers_Insert
, Suppliers_Update
e Suppliers_Delete
, como ilustra a Figura 4.
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.
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:
- Atualizando o
Suppliers_Select
procedimento armazenado para retornar aFullContactName
coluna computada e - 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 SuppliersTableAdapter
mouse 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.
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 SuppliersDataTable
arquivo . 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.
Figura 7: A FullContactName
coluna está marcada como somente leitura (clique para exibir a imagem em tamanho real)
Etapa 5: Adicionando umGetSupplierBySupplierID
mé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.
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.
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.
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 CategoryName
propriedades , ContactName
e 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.
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 CompanyName
Contato, 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
) .
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.
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 , UPDATE
e 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.