Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Un null
valor en el origen de datos indica que el valor es desconocido. En las consultas LINQ to Entities, puede comprobar si hay valores NULL para que determinados cálculos o comparaciones solo se realicen en filas que tengan datos válidos o no NULL. Sin embargo, la semántica de CLR null puede diferir de la semántica nula del origen de datos. La mayoría de las bases de datos usan una versión de lógica de tres valores para controlar comparaciones nulas. Es decir, una comparación con un valor NULL no se evalúa como true
o false
, se evalúa como unknown
. A menudo se trata de una implementación de nulos ANSI, pero esto no siempre es el caso.
De forma predeterminada en SQL Server, la comparación null-equals-null devuelve un valor NULL. En el ejemplo siguiente, las filas donde ShipDate
es NULL se excluyen del conjunto de resultados y la instrucción Transact-SQL devolvería 0 filas.
-- Find order details and orders with no ship date.
SELECT h.SalesOrderID
FROM Sales.SalesOrderHeader h
JOIN Sales.SalesOrderDetail o ON o.SalesOrderID = h.SalesOrderID
WHERE h.ShipDate IS Null
Esto es muy diferente de la semántica de NULL de CLR, donde la comparación de igualdad entre valores NULL devuelve true.
La siguiente consulta LINQ se expresa en CLR, pero se ejecuta en el origen de datos. Dado que no hay ninguna garantía de que se respetará la semántica clR en el origen de datos, el comportamiento esperado es indeterminado.
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;
ObjectSet<SalesOrderDetail> details = context.SalesOrderDetails;
var query =
from order in orders
join detail in details
on order.SalesOrderID
equals detail.SalesOrderID
where order.ShipDate == null
select order.SalesOrderID;
foreach (var OrderID in query)
{
Console.WriteLine($"OrderID : {OrderID}");
}
}
Using context As New AdventureWorksEntities()
Dim orders As ObjectSet(Of SalesOrderHeader) = context.SalesOrderHeaders
Dim details As ObjectSet(Of SalesOrderDetail) = context.SalesOrderDetails
Dim query = _
From order In orders _
Join detail In details _
On order.SalesOrderID _
Equals detail.SalesOrderID _
Where order.ShipDate = Nothing
Select order.SalesOrderID
For Each orderID In query
Console.WriteLine("OrderID: {0} ", orderID)
Next
End Using
Selectores de clave
Un selector de claves es una función que se usa en los operadores de consulta estándar para extraer una clave de un elemento. En la función del selector de claves, una expresión se puede comparar con una constante. La semántica de CLR null se muestra si una expresión se compara con una constante null o si se comparan dos constantes null. La semántica de NULL del almacén se exhibe si se comparan dos columnas con valores NULL del origen de datos. Los selectores de claves se encuentran en muchos de los operadores de consulta estándar de agrupación y ordenación, como GroupBy, y se usan para seleccionar claves para ordenar o agrupar los resultados de la consulta.
Propiedad nula en un objeto nulo
En Entity Framework, las propiedades de un objeto NULL son NULL. Al intentar hacer referencia a una propiedad de un objeto NULL en CLR, recibirá un NullReferenceException. Cuando una consulta LINQ implica una propiedad de un objeto NULL, esto puede dar lugar a un comportamiento incoherente.
Por ejemplo, en la consulta siguiente, la conversión a NewProduct
se realiza en la capa de árbol de comandos, lo que podría dar lugar a que la propiedad Introduced
sea *null*. Si la base de datos define comparaciones nulas de forma que la DateTime comparación se evalúa como true, se incluirá la fila.
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
DateTime dt = new DateTime();
var query = context.Products
.Where(p => (p as NewProduct).Introduced > dt)
.Select(x => x);
}
Using context As New AdventureWorksEntities()
Dim dt As DateTime = New DateTime()
Dim query = context.Products _
.Where(Function(p) _
((DirectCast(p, NewProduct)).Introduced > dt)) _
.Select(Function(x) x)
End Using
Pasar colecciones NULL a funciones de agregado
En LINQ to Entities, cuando se pasa una colección que admite IQueryable
a una función de agregado, las operaciones de agregado se realizan en la base de datos. Puede haber diferencias en los resultados de una consulta que se realizó en memoria y una consulta que se realizó en la base de datos. Con una consulta en memoria, si no hay coincidencias, la consulta devuelve cero. En la base de datos, la misma consulta devuelve null
. Si se pasa un null
valor a una función de agregado LINQ, se producirá una excepción. Para aceptar posibles valores null
, convierta los tipos y las propiedades de los tipos que reciben resultados de consulta a tipos de valor anulables.