Perguntas frequentes

As seções a seguir respondem a alguns problemas comuns que você pode encontrar ao implementar o LINQ.

Problemas adicionais são resolvidos na solução de problemas.

Não é possível conectar

Não consigo me conectar a meu banco de dados.

Verifique se sua cadeia de conexão está correta e se sua instância do SQL Server está sendo executada. Observe também que o LINQ to SQL exige que o protocolo de pipes nomeados esteja ativado. Para obter mais informações, consulte Learning by Walkthroughs.

Alterações perdidas do banco de dados

Fiz uma alteração nos dados no banco de dados, mas, quando executei o aplicativo, a alteração não estava mais lá.

Verifique se você chamou SubmitChanges para salvar os resultados no banco de dados.

Conexão do banco de dados: há quanto tempo está aberta?

Quanto tempo a conexão do banco de dados permanece aberta?

Uma conexão geralmente permanece aberta até você consumir os resultados da consulta. Se você pretende processar todos os resultados e não se opõe a armazenar em cache os resultados, aplique ToList à consulta. Em cenários comuns onde cada objeto é processado somente uma vez, o modelo de streaming é superior no DataReader e no LINQ to SQL.

Os detalhes exatos do uso da conexão dependem do seguinte:

Atualizar sem consultar

Posso atualizar os dados da tabela sem primeiro consultar o banco de dados?

Embora o LINQ to SQL não tenha comandos de atualização baseados em conjunto, você pode usar qualquer uma das seguintes técnicas para atualizar sem consultar primeiro:

  • Use ExecuteCommand para enviar o código SQL.

  • Crie uma nova instância do objeto e inicialize todos os valores atuais (campos) que afetam a atualização. Anexe o objeto ao DataContext usando Attach e modifique o campo que você deseja alterar.

Resultados inesperados da consulta

Minha consulta está retornando resultados inesperados. Como posso inspecionar o que está ocorrendo?

O LINQ to SQL fornece várias ferramentas para inspecionar o código SQL que produz. Um dos mais importantes é Log. Para obter mais informações, consulte Suporte de depuração.

Resultados inesperados de procedimentos armazenados

Tenho um procedimento armazenado cujo valor de retorno é calculado por ‘MAX()’. Quando eu arrasto o procedimento armazenado para a superfície do Designer Relacional de Objetos, o valor de retorno não está correto.

O LINQ to SQL fornece duas maneiras de retornar valores gerados por banco de dados por meio de procedimentos armazenados:

  • Nomeando o resultado de saída.

  • Especificando explicitamente um parâmetro de saída.

O código a seguir é um exemplo de saída incorreta. Como o LINQ to SQL não pode mapear os resultados, ele sempre retorna 0:

create procedure proc2

as

begin

select max(i) from t where name like 'hello'

end

O código a seguir é um exemplo de saída correta usando um parâmetro de saída:

create procedure proc2

@result int OUTPUT

as

select @result = MAX(i) from t where name like 'hello'

go

O código a seguir é um exemplo de saída correta nomeando o resultado de saída:

create procedure proc2

as

begin

select nax(i) AS MaxResult from t where name like 'hello'

end

Para obter mais informações, consulte Personalizando operações usando procedimentos armazenados.

Erros de serialização

Quando eu tento serializar, obtenho o seguinte erro: “Tipo 'System.Data.Linq.ChangeTracker+StandardChangeTracker' ... não está marcado como serializável.”

A geração de código no LINQ to SQL dá suporte à DataContractSerializer serialização. Ela não dá suporte a XmlSerializer ou BinaryFormatter. Para obter mais informações, consulte Serialização.

Vários arquivos DBML

Quando eu tenho vários arquivos DBML que compartilham algumas tabelas em comum, eu obtenho um erro do compilador.

Defina as propriedades Namespace do Contexto e Namespace da Entidade do Designer Relacional de Objetos para um valor diferente para cada arquivo DBML. Essa abordagem elimina a colisão nome/namespace.

Evitando a configuração explícita de valores gerados por banco de dados em Insert ou Update

Tenho uma tabela de banco de dados com uma coluna ‘DataCreated’ que usa como padrão o ‘Getdate()’ do SQL. Quando tento inserir um novo registro usando o LINQ to SQL, o valor é definido como ‘NULO’. Eu gostaria que ele fosse definido como o padrão do banco de dados.

O LINQ to SQL trata essa situação automaticamente para colunas de identidade (incremento automático) e rowguidcol (GUID gerado por banco de dados) e carimbo de data/hora. Em outros casos, você deve definir manualmente as propriedades IsDbGenerated=true e AutoSync=Always/OnInsert/OnUpdate.

Vários DataLoadOptions

Posso especificar opções de carregamento adicionais sem substituir as primeiras?

Sim. A primeira não é substituída, como no exemplo a seguir:

Dim dlo As New DataLoadOptions()
dlo.LoadWith(Of Order)(Function(o As Order) o.Customer)
dlo.LoadWith(Of Order)(Function(o As Order) o.OrderDetails)
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<Order>(o => o.Customer);
dlo.LoadWith<Order>(o => o.OrderDetails);

Erros ao usar o SQL Compact 3.5

Recebo um erro quando arrasto as tabelas para fora de um banco de dados do SQL Server Compact 3.5.

O Object Relational Designer não dá suporte ao SQL Server Compact 3.5, embora o runtime LINQ to SQL dê suporte. Nesta situação, você deve criar suas próprias classes de entidade e adicionar os atributos apropriados.

Erros nas relações de herança

Usei o formato de herança da caixa de ferramentas no Designer Relacional de Objetos para conectar duas entidades, mas obtive erros.

Criar a relação não é suficiente. Você deve fornecer informações como a coluna do discriminador, o valor do discriminador da classe base e o valor do discriminador da classe derivada.

Modelo do provedor

Um modelo de provedor público está disponível?

Nenhum modelo de provedor público está disponível. No momento, LINQ to SQL dá suporte apenas a SQL Server e SQL Server Compact 3,5.

Ataques de injeção de SQL

Como LINQ to SQL é protegido contra ataques de injeção de SQL?

A injeção de SQL tem sido um risco significativo para consultas tradicionais de SQL formadas por meio da concatenação da entrada do usuário. O LINQ to SQL evita essa injeção usando o SqlParameter em consultas. A entrada do usuário é transformada em valores de parâmetro. Essa abordagem impede que os comandos mal-intencionados sejam usados da entrada do cliente.

Alterando o sinalizador somente leitura em arquivos DBML

Como posso eliminar configuradores de algumas propriedades quando crio um modelo de objeto de um arquivo DBML?

Siga as etapas a seguir para este cenário avançado:

  1. No arquivo .dbml, modifique a propriedade alterando o sinalizador do IsReadOnly para True.

  2. Adicione uma classe parcial. Crie um construtor com parâmetros para os membros somente leitura.

  3. Examine o valor padrão UpdateCheck (Never) para determinar se este é o valor correto para seu aplicativo.

    Cuidado

    Se você estiver usando um Designer Relacional de Objetos no Visual Studio, as suas alterações podem ter sido substituídas.

APTCA

O System.Data.Linq está marcado para ser usado pelo código parcialmente confiável?

Sim, o conjunto System.Data.Linq.dll está entre os assemblies do .NET Framework marcados com o atributo AllowPartiallyTrustedCallersAttribute. Sem esta marcação, os assemblies no .NET Framework são destinados para o uso somente pelo código totalmente confiável.

O principal cenário no LINQ to SQL para permitir chamadores parcialmente confiáveis é permitir que o assembly do LINQ to SQL seja acessado de aplicativos Web, onde a configuração de confiança seja Média.

Dados de mapeamento de várias tabelas

Os dados na minha entidade vêm de várias tabelas. Como posso mapeá-los?

Você pode criar uma exibição em um banco de dados e mapear a entidade para a exibição. O LINQ to SQL gera o mesmo SQL para exibições da mesma forma que faz para tabelas.

Observação

O uso de exibições nesse cenário tem limitações. Essa abordagem funciona com mais segurança quando as operações realizadas no Table<TEntity> têm suporte pela exibição subjacente. Somente você sabe quais operações são desejadas. Por exemplo, a maioria dos aplicativos são somente leitura, e outro número grande realiza operações Create/Update/Delete somente usando os procedimentos armazenados em exibições.

Pool de conexões

Há uma construção que possa ajudar com o pool de DataContext?

Não tente reutilizar instâncias do DataContext. Cada DataContext mantém o estado (incluindo um cache de identidade) para uma determinada sessão de edição/consulta. Para obter as novas instâncias com base no estado atual do banco de dados, use um novo DataContext.

Você ainda pode usar o pool de conexões do ADO.NET subjacente. Para obter mais informações, consulte Pool de Conexões do SQL Server (ADO.NET).

O segundo DataContext não é atualizado

Eu usei uma instância do DataContext para armazenar valores no banco de dados. No entanto, um segundo DataContext no mesmo banco de dados não reflete os valores atualizados. A segunda instância do DataContext parece retornar os valores armazenados em cache.

Este comportamento ocorre por design. O LINQ to SQL continua a retornar as mesmas instâncias/valores que você viu na primeira instância. Quando você faz atualizações, usa a simultaneidade otimista. Os dados originais são usados para verificar o estado atual do banco de dados e declarar que ainda estão de fato inalterados. Se eles forem alterados, um conflito ocorre e seu aplicativo deve resolvê-lo. Uma opção do aplicativo é redefinir o estado original para o estado atual do banco de dados e tentar novamente a atualização. Para mais informações, confira Como gerenciar conflitos de alteração.

Você também pode definir o ObjectTrackingEnabled como falso, o que desativa o cache e o controle de alterações. Você pode então recuperar os valores mais recentes toda vez que consultar.

Não é possível chamar SubmitChanges no modo somente leitura

Quando eu tento chamar SubmitChanges no modo somente leitura, obtenho um erro.

O modo somente leitura desativa a capacidade de o contexto controlar as alterações.