Eu quero executar uma consulta como esta
var result = from entry in table
where entry.something == null
select entry;
e obter um IS NULL
gerado.
Editado: Após as duas primeiras respostas, sinto a necessidade de esclarecer que estou usando o Entity Framework e não Linq to SQL. O método object.Equals () não parece funcionar no EF.
Edição nº 2: A consulta acima funciona conforme o esperado. É gerado corretamente IS NULL
. Meu código de produção, entretanto, era
value = null;
var result = from entry in table
where entry.something == value
select entry;
e o SQL gerado era something = @p; @p = NULL
. Parece que EF traduz corretamente a expressão constante, mas se uma variável estiver envolvida, ela a trata como uma comparação normal. Faz sentido, na verdade. Vou fechar essa questão
.net
entity-framework
ado.net
Adrian Zanescu
fonte
fonte
Respostas:
Solução alternativa para Linq-to-SQL:
Solução alternativa para Linq-to-Entities (ouch!):
Este é um bug desagradável que me mordeu várias vezes.
Se este bug afetou você também, visite o relatório de bug no UserVoice e informe a Microsoft que este bug afetou você também.Edit: Este bug está sendo corrigido no EF 4.5 ! Obrigado a todos por votar a favor deste bug!
Para compatibilidade com versões anteriores, será opcional - você precisa habilitar manualmente uma configuração para que
entry == value
funcione. Nenhuma palavra ainda sobre o que é essa configuração. Fique ligado!Edição 2: De acordo com esta postagem da equipe EF, esse problema foi corrigido no EF6! Uau!
Isso significa que o código existente que depende do comportamento antigo (
null != null
mas apenas quando comparado a uma variável) precisará ser alterado para não depender desse comportamento ou definidoUseCSharpNullComparisonBehavior
como false para usar o comportamento antigo quebrado.fonte
(var result = from ...; if(value.HasValue) result = result.Where(e => e.something == value) else result = result.Where(e => e.something == null);
(where Object.Equals(entry.something,value))
Desde o Entity Framework 5.0, você pode usar o seguinte código para resolver seu problema:
Isso deve resolver seus problemas, pois o Entity Framerwork usará a comparação nula 'C # like'.
fonte
Há uma solução um pouco mais simples que funciona com LINQ to Entities:
Isso funciona porque, como AZ observou, LINQ to Entities casos especiais x == null (ou seja, uma comparação de igualdade contra a constante nula) e traduz para x IS NULL.
No momento, estamos considerando alterar esse comportamento para introduzir as comparações de compensação automaticamente se ambos os lados da igualdade forem anuláveis. No entanto, existem alguns desafios:
Em qualquer caso, se vamos trabalhar nisso vai depender muito da prioridade relativa que nossos clientes atribuem a isso. Se você se preocupa com o problema, incentivo-o a votar em nosso novo site de sugestões de recursos: https://data.uservoice.com .
fonte
Se for um tipo anulável, talvez tente usar a propriedade HasValue?
Não tem nenhum EF para testar aqui ... apenas uma sugestão =)
fonte
== null
não é atingido pelo bug de qualquer maneira. O objetivo é filtrar pelo valor de uma variável, cujo valor pode ser nulo, e fazer com que o valor nulo encontre os registros nulos.(x => x.Column == null)
funcionar. :)System.NullReferenceException
, visto que o objeto allready é nulo!Referência do MSDN : LINQ to SQL: consulta integrada à linguagem .NET para dados relacionais
fonte
para lidar com comparações nulas, use em
Object.Equals()
vez de==
verifique esta referência
fonte
null
,Object.Equals(null)
e se oObject
próprio for nulo?Ressaltando que todas as sugestões do Entity Framework <6.0 geram um SQL estranho. Veja o segundo exemplo para correção "limpa".
Solução Alternativa Ridícula
resulta em SQL como:
Outrageous Workaround
Se você deseja gerar um SQL mais limpo, algo como:
resulta no que você queria em primeiro lugar:
fonte
A consulta acima funciona conforme o esperado. Ele gera IS NULL corretamente. Meu código de produção, entretanto, era
e o SQL gerado era algo = @p; @p = NULL. Parece que EF traduz corretamente a expressão constante, mas se uma variável estiver envolvida, ela a trata como uma comparação normal. Faz sentido, na verdade.
fonte
Parece que o Linq2Sql também tem esse "problema". Parece que há um motivo válido para esse comportamento devido ao fato de ANSI NULLs estarem ON ou OFF, mas confunde a mente por que um "== null" direto na verdade funcionará como você esperaria.
fonte
Pessoalmente, prefiro:
sobre
porque evita a repetição - embora isso não seja matematicamente exato, mas se encaixa bem na maioria dos casos.
fonte
Não posso comentar o post da divega, mas entre as diferentes soluções apresentadas aqui, a solução da divega produz o melhor SQL. Tanto o desempenho quanto o comprimento. Acabei de verificar com o SQL Server Profiler e olhando o plano de execução (com "SET STATISTICS PROFILE ON").
fonte
Infelizmente, no Entity Framework 5 DbContext o problema ainda não foi corrigido.
Usei esta solução alternativa (funciona com MSSQL 2012, mas a configuração ANSI NULLS pode ser preterida em qualquer versão futura do MSSQL).
Deve-se observar que é uma solução alternativa suja, mas que pode ser implementada muito rapidamente e funciona para todas as consultas.
fonte
Se você preferir usar a sintaxe do método (lambda) como eu, você poderia fazer a mesma coisa assim:
fonte
Use isso
fonte