Nelle sezioni seguenti vengono fornite le risposte ad alcuni problemi comuni che possono verificarsi durante l'implementazione di LINQ.
In Risoluzione dei problemi vengono esaminati altri problemi.
Impossibile connettersi
Non è possibile connettersi al database.
Assicurarsi che la stringa di connessione sia corretta e che l'istanza SQL Server sia in esecuzione. Tenere inoltre presente che LINQ to SQL richiede che sia abilitato il protocollo Named Pipes. Per altre informazioni, vedere Apprendimento tramite procedure dettagliate.
Perdita delle modifiche al database
Quando si riesegue l'applicazione dopo avere apportato una modifica ai dati presenti nel database, la modifica va persa.
Accertarsi di chiamare SubmitChanges per salvare i risultati nel database.
Durata di una connessione di database aperta
Per quanto tempo rimane aperta la connessione di database?
Una connessione rimane in genere aperta finché non si usano i risultati della query. Se si prevede di impiegare tempo per elaborare tutti i risultati ed è possibile memorizzare nella cache i risultati, applicare ToList alla query. Negli scenari comuni dove ogni oggetto viene elaborato solo una volta, il modello di flusso è superiore in DataReader
e LINQ to SQL.
I dettagli esatti di utilizzo della connessione dipendono dagli elementi seguenti:
Stato della connessione se DataContext viene costruito con un oggetto connessione.
Impostazioni della stringa di connessione, ad esempio abilitando MARS (Multiple Active Result Sets). Per altre informazioni, vedere MARS (Multiple Active Result Sets).
Aggiornamento senza query
È possibile aggiornare i dati della tabella senza prima eseguire una query sul database?
Sebbene LINQ to SQL non disponga di comandi di aggiornamento basati su set, è possibile usare le tecniche seguenti per aggiornare senza prima eseguire una query:
Usare ExecuteCommand per inviare il codice SQL.
Creare una nuova istanza dell'oggetto e inizializzare tutti i valori (campi) correnti che influiscono sull'aggiornamento. Associare quindi l'oggetto a DataContext usando Attach e modificare il campo desiderato.
Risultati imprevisti delle query
La query restituisce risultati imprevisti. Come è possibile controllare quello che si sta verificando?
LINQ to SQL fornisce molti strumenti per controllare il codice SQL generato. Uno dei più importanti è Log. Per altre informazioni, vedere Debug supporto.
Risultati imprevisti delle stored procedure
Il valore restituito di una stored procedure viene calcolato da "MAX()". Quando si trascina la stored procedure nell'area di Object Relational Designer, il valore restituito non è corretto.
LINQ to SQL fornisce due modalità per restituire i valori generati dal database tramite le stored procedure:
Assegnando un nome al risultato di output.
Specificando in modo esplicito un parametro di output.
Di seguito viene riportato un esempio di output non corretto. Poiché in LINQ to SQL non è possibile eseguire il mapping dei risultati, viene restituito sempre 0:
create procedure proc2
as
begin
select max(i) from t where name like 'hello'
end
Di seguito viene riportato un esempio di output corretto usando un parametro di output:
create procedure proc2
@result int OUTPUT
as
select @result = MAX(i) from t where name like 'hello'
go
Di seguito viene riportato un esempio di output corretto assegnando un nome al risultato di output:
create procedure proc2
as
begin
select nax(i) AS MaxResult from t where name like 'hello'
end
Per altre informazioni, vedere Personalizzazione di operazioni usando stored procedure.
Errori di inizializzazione
Durante la serializzazione, si verifica il seguente errore: "Tipo 'System.Data.Linq.ChangeTracker+StandardChangeTracker' ... non contrassegnato come serializzabile".
La generazione del codice in LINQ to SQL supporta la serializzazione DataContractSerializer. Non supporta XmlSerializer o BinaryFormatter. Per altre informazioni, vedere Serializzazione.
Più file DBML
Quando si dispone di più file DBML che condividono alcune tabelle, si verifica un errore del compilatore.
Impostare le proprietà Context Namespace ed Entity Namespace da Object Relational Designer su un valore distinto per ogni file DBML. Questo approccio elimina il conflitto di nome/spazio dei nomi.
Come evitare l'impostazione esplicita dei valori generati dal database nelle operazioni di inserimento o aggiornamento
Quando in una tabella di database con una colonna "DateCreated" la cui impostazione predefinita è SQL "Getdate()". Quando si tenta di inserire un nuovo record usando LINQ to SQL, il valore viene impostato su "NULL". anziché sul valore predefinito del database.
LINQ to SQL gestisce automaticamente questa situazione per le colonne Identity (incremento automatico) e rowguidcol (GUID generato dal database) e timestamp. Negli altri casi, impostare manualmente le proprietà IsDbGenerated=true
e AutoSync=Always/OnInsert/OnUpdate.
Più valori DataLoadOptions
È possibile specificare opzioni di caricamento aggiuntive senza sovrascrivere la prima?
Sì. La prima opzione non viene sovrascritta, come illustrato nell'esempio seguente:
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);
Errori durante l'uso di SQL Compact 3.5
Quando si trascinano le tabelle al di fuori di un database SQL Server Compact 3.5, si verifica un errore.
Object Relational Designer non supporta SQL Server Compact 3.5, anche se il runtime LINQ to SQL sì. In questa situazione, è necessario creare classi dell'entità personalizzate e aggiungere gli attributi adatti.
Errori nelle relazioni di ereditarietà
Quando si usa la forma di ereditarietà della casella degli strumenti in Object Relational Designer per connettere due entità, si verificano errori.
Non è sufficiente creare la relazione. È necessario fornire informazioni quali la colonna del discriminatore, il valore del discriminatore della classe base e il valore del discriminatore della classe derivata.
Modello provider
È disponibile un modello provider pubblico?
Non è disponibile alcun un modello provider pubblico. Al momento, LINQ to SQL supporta solo SQL Server e SQL Server Compact 3.5.
Attacchi SQL injection
Come viene protetto LINQ to SQL dagli attacchi SQL injection?
L'intrusione nel codice SQL ha rappresentato un pericolo significativo per le query SQL tradizionali formate concatenando l'input dell'utente. LINQ to SQL evita tale intrusione usando SqlParameter nelle query. L'input dell'utente viene convertito in valori di parametro. Questo approccio impedisce l'uso di comandi dannosi dall'input del cliente.
Modifica del flag di sola lettura nei file DBML
Come è possibile eliminare i metodi di impostazione da alcune proprietà quando si crea un modello a oggetti da un file DBML?
Attenersi alla procedura riportata di seguito per questo scenario avanzato:
Nel file con estensione dbml modificare la proprietà impostando il flag IsReadOnly su
True
.Aggiungere una classe parziale. Creare un costruttore con i parametri per i membri di sola lettura.
Esaminare il valore UpdateCheck predefinito (Never) per determinare se questo valore è corretto per l'applicazione.
Attenzione
Se si usa Object Relational Designer in Visual Studio, le modifiche potrebbero essere sovrascritte.
APTCA
System.Data.Linq è contrassegnato per l'uso da codice parzialmente attendibile?
Sì, l'assembly System.Data.Linq.dll è tra gli assembly .NET Framework contrassegnati con l'attributo AllowPartiallyTrustedCallersAttribute. Senza questo contrassegno, gli assembly in .NET Framework vengono usati solo da codice completamente attendibile.
Lo scenario principale in LINQ to SQL per consentire chiamanti parzialmente attendibili è fornire all'assembly LINQ to SQL l'accesso dalle applicazioni Web, dove la configurazione trust è impostata su Medio.
Esecuzione del mapping dei dati da più tabelle
I dati dell'entità derivano da più tabelle. Come è possibile eseguirne il mapping?
È possibile creare una visualizzazione in un database ed eseguire il mapping dell'entità alla visualizzazione. LINQ to SQL genera lo stesso codice SQL per le visualizzazioni come per le tabelle.
Nota
L'utilizzo di visualizzazioni in questo scenario presenta delle limitazioni. Questo approccio funziona in modo più sicuro quando le operazioni eseguite su Table<TEntity> vengono supportate dalla visualizzazione sottostante. Solo l'utente conosce le operazioni desiderate da eseguire. Ad esempio, la maggior parte delle applicazioni sono di sola lettura mentre altre applicazioni eseguono le operazioni Create
/Update
/Delete
solo usando le stored procedure sulle visualizzazioni.
Pool di connessioni
È disponibile un costrutto che possa facilitare il pool DataContext?
Non tentare di riutilizzare le istanze di DataContext. Ogni oggetto DataContext conserva lo stato (inclusa una cache delle identità) per una determinata sessione di modifica/query. Per ottenere nuove istanze basate sullo stato corrente del database, usare un nuovo oggetto DataContext.
È tuttavia possibile usare il pool di connessioni ADO.NET sottostante. Per altre informazioni, vedere Pool di connessioni SQL Server (ADO.NET).
Il secondo oggetto DataContext non viene aggiornato
Un'istanza di DataContext è stata usata per archiviare i valori nel database. Tuttavia, un secondo oggetto DataContext nello stesso database non riflette i valori aggiornati. La seconda istanza DataContext sembra restituire i valori memorizzati nella cache.
Questo comportamento è impostato a livello di progettazione. LINQ to SQL continua a restituire gli stessi valori o le stesse istanze specificate nella prima istanza. Quando si effettuano gli aggiornamenti, usare la concorrenza ottimistica. I dati originali vengono usati per controllare lo stato corrente del database in modo da asserire che risulta ancora invariato. Se è stato modificato, si verifica un conflitto e l'applicazione deve risolverlo. Un'opzione dell'applicazione è reimpostare lo stato originale allo stato corrente del database e provare nuovamente l'aggiornamento. Per altre informazioni, vedere Procedura: Gestire i conflitti di modifiche.
È anche possibile impostare ObjectTrackingEnabled su false, in modo da disattivare la memorizzazione nella cache e la ricerca delle modifiche. È quindi possibile recuperare gli ultimi valori ogni volta che si esegue una query.
Impossibile chiamare SubmitChanges in modalità di sola lettura
Quando si tenta di chiamare SubmitChanges in modalità di sola lettura, si verifica un errore.
La modalità di sola lettura non consente al contesto di tenere traccia delle modifiche.