As seções a seguir respondem a alguns problemas comuns que você pode encontrar ao implementar o LINQ.
Problemas adicionais são abordados na Solução de problemas.
Não é possível conectar
Não consigo ligar à minha base de dados.
Verifique se a cadeia de conexão está correta e se a instância do SQL Server está em execução. Observe também que o LINQ to SQL requer que o protocolo Named Pipes esteja habilitado. Para obter mais informações, consulte Aprendendo por passo a passo.
Alterações no banco de dados perdidas
Fiz uma alteração nos dados no banco de dados, mas quando executei novamente meu aplicativo, a alteração não estava mais lá.
Certifique-se de ligar SubmitChanges para salvar os resultados no banco de dados.
Conexão de banco de dados: Abrir por quanto tempo?
Por quanto tempo minha conexão de banco de dados permanece aberta?
Uma conexão normalmente permanece aberta até que você consuma os resultados da consulta. Se você espera levar tempo para processar todos os resultados e não se opõe a armazenar os resultados em cache, aplique ToList à consulta. Em cenários comuns em que cada objeto é processado apenas uma vez, o modelo de streaming é superior em ambos e DataReader
LINQ to SQL.
Os detalhes exatos do uso da conexão dependem do seguinte:
Status da conexão se o DataContext for construído com um objeto de conexão.
Configurações de cadeia de conexão (por exemplo, habilitando vários conjuntos de resultados ativos (MARS). Para obter mais informações, consulte Vários conjuntos de resultados ativos (MARS).
Atualizando sem consultar
Posso atualizar os dados da tabela sem consultar primeiro o banco de dados?
Embora o LINQ to SQL não tenha comandos de atualização baseados em conjunto, você pode usar uma das seguintes técnicas para atualizar sem consultar primeiro:
Use ExecuteCommand para enviar código SQL.
Crie uma nova instância do objeto e inicialize todos os valores atuais (campos) que afetam a atualização. Em seguida, anexe o objeto ao DataContext usando Attach e modifique o campo que 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 gera. Um dos mais importantes é Log. Para obter mais informações, consulte Suporte de depuração.
Resultados inesperados do procedimento armazenado
Tenho um procedimento armazenado cujo valor de retorno é calculado por 'MAX()'. Quando arrasto o procedimento armazenado para a superfície do O/R Designer, 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 da saída.
Especificando explicitamente um parâmetro de saída.
A seguir está 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
A seguir está 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
A seguir está 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 tento serializar, recebo 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 oferece suporte DataContractSerializer à serialização. Não suporta XmlSerializer ou BinaryFormatter. Para obter mais informações, consulte Serialização.
Vários arquivos DBML
Quando tenho vários arquivos DBML que compartilham algumas tabelas em comum, recebo um erro de compilador.
Defina as propriedades Context Namespace e Entity Namespace do Object Relational Designer para um valor distinto para cada arquivo DBML. Essa abordagem elimina a colisão nome/namespace.
Evitando a configuração explícita de valores gerados pelo banco de dados ao inserir ou atualizar
Tenho uma tabela de banco de dados com uma coluna 'DateCreated' cujo padrão é SQL 'Getdate()'. Quando tento inserir um novo registro usando LINQ to SQL, o valor é definido como 'NULL'. Eu esperaria que ele fosse definido como o padrão do banco de dados.
O LINQ to SQL lida com 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 IsDbGenerated=true
manualmente e AutoSync/OnUpdate=AlwaysOnInsert/propriedades.
Várias DataLoadOptions
Posso especificar opções de carregamento adicionais sem substituir a primeira?
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 usando o SQL Compact 3.5
Recebo um erro quando arrasto tabelas para fora de um banco de dados do SQL Server Compact 3.5.
O Object Relational Designer não oferece suporte ao SQL Server Compact 3.5, embora o tempo de execução do LINQ to SQL o faça. Nessa situação, você deve criar suas próprias classes de entidade e adicionar os atributos apropriados.
Erros nas relações de herança
Usei a forma de herança da caixa de ferramentas no Object Relational Designer para conectar duas entidades, mas recebo erros.
Criar a relação não é suficiente. Você deve fornecer informações como a coluna discriminador, o valor discriminador de classe base e o valor discriminador de classe derivado.
Modelo de provedor
Existe um modelo de fornecedor público disponível?
Nenhum modelo de provedor público está disponível. No momento, o LINQ to SQL oferece suporte somente ao SQL Server e ao SQL Server Compact 3.5.
Ataques de injeção de SQL
Como o LINQ to SQL é protegido contra ataques de injeção de SQL?
A injeção de SQL tem sido um risco significativo para consultas SQL tradicionais formadas pela concatenação da entrada do usuário. O LINQ to SQL evita essa injeção usando SqlParameter em consultas. A entrada do usuário é transformada em valores de parâmetro. Essa abordagem impede que comandos mal-intencionados sejam usados a partir da entrada do cliente.
Alterando o sinalizador somente leitura em arquivos DBML
Como elimino setters de algumas propriedades quando crio um modelo de objeto a partir de um arquivo DBML?
Execute as seguintes etapas para este cenário avançado:
No arquivo .dbml, modifique a propriedade alterando o IsReadOnly sinalizador para
True
.Adicione uma classe parcial. Crie um construtor com parâmetros para os membros somente leitura.
Analise o valor padrão UpdateCheck (Never) para determinar se esse é o valor correto para seu aplicativo.
Atenção
Se você estiver usando o Object Relational Designer no Visual Studio, suas alterações podem ser substituídas.
APTCA
System.Data.Linq está marcado para uso por código parcialmente confiável?
Sim, o assembly System.Data.Linq.dll está entre os assemblies do .NET Framework marcados com o AllowPartiallyTrustedCallersAttribute atributo. Sem essa marcação, assemblies no .NET Framework destinam-se ao uso somente por código totalmente confiável.
O cenário principal no LINQ to SQL para permitir chamadores parcialmente confiáveis é permitir que o assembly LINQ to SQL seja acessado a partir de aplicativos Web, onde a configuração de confiança é Média.
Mapeando dados de várias tabelas
Os dados na minha entidade vêm de várias tabelas. Como faço para mapeá-lo?
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 que para tabelas.
Nota
O uso de modos de exibição neste cenário tem limitações. Essa abordagem funciona com mais segurança quando as operações executadas são Table<TEntity> suportadas pela exibição subjacente. Só você sabe a que operações se destinam. Por exemplo, a maioria dos aplicativos é somente leitura e outro número considerável executa Create
//Update
Delete
operações somente usando procedimentos armazenados em modos de exibição.
Conjunto de Ligações
Existe uma construção que pode ajudar com o pool DataContext?
Não tente reutilizar instâncias do DataContext. Cada DataContext um mantém o estado (incluindo um cache de identidade) para uma sessão de edição/consulta específica. Para obter novas instâncias com base no estado atual do banco de dados, use um novo DataContextarquivo .
Você ainda pode usar o pool de conexões de ADO.NET subjacente. Para obter mais informações, consulte Pool de conexões do SQL Server (ADO.NET).
Segundo DataContext não é atualizado
Eu usei uma instância de 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 DataContext parece retornar valores armazenados em cache.
Este comportamento é a predefinição. O LINQ to SQL continua a retornar as mesmas instâncias/valores que você viu na primeira instância. Ao fazer atualizações, você usa simultaneidade otimista. Os dados originais são usados para verificar o estado atual do banco de dados para afirmar que, de fato, ele ainda está inalterado. Se tiver sido alterado, ocorrerá um conflito e o seu pedido terá de o resolver. Uma opção do seu aplicativo é redefinir o estado original para o estado atual do banco de dados e tentar a atualização novamente. Para obter mais informações, consulte Como gerenciar conflitos de alteração.
Você também pode definir ObjectTrackingEnabled como false, o que desativa o cache e o controle de alterações. Em seguida, você pode recuperar os valores mais recentes sempre que consultar.
Não é possível chamar SubmitChanges no modo somente leitura
Quando tento chamar SubmitChanges no modo somente leitura, recebo um erro.
O modo somente leitura desativa a capacidade do contexto de controlar alterações.