Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Un valore null nell'origine dati indica che il valore è sconosciuto. Nella query LINQ to Entities è possibile verificare la presenza di valori Null in modo che alcuni calcoli o confronti vengano eseguiti solo sulle righe che includono dati validi, ovvero non NULL. Tuttavia, la semantica dei valori Null di CLR può differire da quella dell'origine dati. La maggior parte dei database utilizza una versione della logica con tre valori per la gestione dei confronti di valori Null. In altre parole, il confronto di un valore Null non restituisce true o false, ma unknown. Spesso, ma non sempre, si tratta di un'implementazione di valori Null ANSI.
Per impostazione predefinita, in SQL Server il confronto tra valori Null con il metodo Equals restituisce un valore Null. Nell'esempio seguente le righe in cui Regione è Null sono escluse dal set di risultati. L'istruzione Transact-SQL restituisce pertanto 0 righe.
-- Find orders and customers with no regions.
SELECT a.[CustomerID]
FROM [Northwind].[dbo].[Customers] a
JOIN [Northwind].[dbo].[Orders] b ON a.Region = b.ShipRegion
WHERE a.Region IS Null
Tale semantica è molto diversa da quella dei valori Null di CLR, in cui dal confronto tra valori Null con il metodo Equals viene restituito True.
La query LINQ seguente è espressa in CLR, ma viene eseguita nell'origine dati. Poiché non esiste alcuna garanzia che venga rispettata la semantica CLR nell'origine dati, il comportamento previsto è indeterminato.
Using NwEntities As New NorthwindEntities()
Dim customers As ObjectQuery(Of Customers) = NwEntities.Customers
Dim orders As ObjectQuery(Of Orders) = NwEntities.Orders
Dim query = _
From c In customers _
Join o In orders On c.Region Equals o.ShipRegion _
Where c.Region = Nothing _
Select c.CustomerID
For Each customerID In query
Console.WriteLine("Customer ID: ", customerID)
Next
End Using
using (NorthwindEntities NwEntities = new NorthwindEntities())
{
ObjectQuery<Customers> customers = NwEntities.Customers;
ObjectQuery<Orders> orders = NwEntities.Orders;
IQueryable<string> query = from c in customers
join o in orders on c.Region equals o.ShipRegion
where c.Region == null
select c.CustomerID;
foreach (string customerID in query)
{
Console.WriteLine("Customer ID: {0}", customerID);
}
}
Selettori di chiave
Un selettore di chiave è una funzione utilizzata negli operatori di query standard per estrarre una chiave da un elemento. Nella funzione del selettore di chiave un'espressione può essere confrontata con una costante. La semantica dei valori Null di CLR viene utilizzata in caso di confronto tra un'espressione e una costante Null o tra due costanti Null. La semantica dei valori Null dell'archivio viene utilizzata se vengono confrontate due colonne con valori Null nell'origine dati. I selettori di chiave sono disponibili in molti operatori di query standard per il raggruppamento e l'ordinamento, come GroupBy e vengono utilizzati per selezionare le chiavi in base alle quali ordinare o raggruppare i risultati delle query.
Proprietà Null in un oggetto Null
In Entity Framework le proprietà di un oggetto Null sono Null. Quando si tenta di fare riferimento a una proprietà di un oggetto Null in CLR, viene ricevuto un oggetto NullReferenceException. Quando una query LINQ include una proprietà di un oggetto Null, è possibile che si verifichi un comportamento incoerente.
Nella query seguente, ad esempio, viene eseguito il cast a NewProduct nel livello dell'albero dei comandi. Ciò potrebbe rendere la proprietà Introduced uguale a Null. Se nel database sono stati definiti confronti di valori Null in modo che il risultato del confronto di DateTime sia True, la riga verrà inclusa.
Using AWEntities As New AdventureWorksEntities()
Dim dt As DateTime = New DateTime()
Dim query = AWEntities.Product _
.Where(Function(p) _
((DirectCast(p, NewProduct)).Introduced > dt)) _
.Select(Function(x) x)
End Using
using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
DateTime dt = new DateTime();
var query = AWEntities.Product
.Where(p => (p as NewProduct).Introduced > dt)
.Select(x => x);
}