In de volgende secties worden enkele veelvoorkomende problemen beantwoord die kunnen optreden wanneer u LINQ implementeert.
Aanvullende problemen worden opgelost in Probleemoplossing.
Kan niet Verbinding maken
Ik kan geen verbinding maken met mijn database.
Zorg ervoor dat uw verbindingsreeks juist is en of uw SQL Server-exemplaar wordt uitgevoerd. Houd er ook rekening mee dat LINQ naar SQL vereist dat het Named Pipes-protocol is ingeschakeld. Zie Learning by Walkthroughs voor meer informatie.
Wijzigingen in database verloren
Ik heb een wijziging aangebracht in gegevens in de database, maar toen ik mijn toepassing herreed, was de wijziging er niet meer.
Zorg ervoor dat u aanroept SubmitChanges om resultaten op te slaan in de database.
Database Verbinding maken ion: Hoe lang openen?
Hoe lang blijft mijn databaseverbinding open?
Een verbinding blijft doorgaans geopend totdat u de queryresultaten gebruikt. Als u verwacht dat u alle resultaten moet verwerken en de resultaten niet in de cache wilt opslaan, moet u van toepassing zijn ToList op de query. In veelvoorkomende scenario's waarbij elk object slechts één keer wordt verwerkt, is het streamingmodel beter in zowel DataReader
ALS LINQ naar SQL.
De exacte details van het verbindingsgebruik zijn afhankelijk van het volgende:
Verbinding maken ionstatus als de DataContext is samengesteld met een verbindingsobject.
Verbinding maken instellingen voor tekenreeksen (bijvoorbeeld het inschakelen van Multiple Active Result Sets (MARS). Zie Meerdere actieve resultatensets (MARS) voor meer informatie.
Bijwerken zonder query's
Kan ik tabelgegevens bijwerken zonder eerst een query uit te voeren op de database?
Hoewel LINQ naar SQL geen op set gebaseerde updateopdrachten heeft, kunt u een van de volgende technieken gebruiken om bij te werken zonder eerst query's uit te voeren:
Gebruik ExecuteCommand dit om SQL-code te verzenden.
Maak een nieuw exemplaar van het object en initialiseer alle huidige waarden (velden) die van invloed zijn op de update. Koppel het object vervolgens aan het DataContext met behulp en Attach wijzig het veld dat u wilt wijzigen.
Onverwachte queryresultaten
Mijn query retourneert onverwachte resultaten. Hoe kan ik controleren wat er gebeurt?
LINQ naar SQL biedt verschillende hulpprogramma's voor het inspecteren van de SQL-code die wordt gegenereerd. Een van de belangrijkste is Log. Zie Ondersteuning voor foutopsporing voor meer informatie.
Onverwachte resultaten van opgeslagen procedures
Ik heb een opgeslagen procedure waarvan de retourwaarde wordt berekend door 'MAX()'. Wanneer ik de opgeslagen procedure naar het O/R Designer-oppervlak sleep, is de retourwaarde niet juist.
LINQ naar SQL biedt twee manieren om door de database gegenereerde waarden te retourneren via opgeslagen procedures:
Door het uitvoerresultaat een naam te geven.
Door expliciet een uitvoerparameter op te geven.
Hier volgt een voorbeeld van onjuiste uitvoer. Omdat LINQ naar SQL de resultaten niet kan toewijzen, wordt altijd 0 geretourneerd:
create procedure proc2
as
begin
select max(i) from t where name like 'hello'
end
Hier volgt een voorbeeld van de juiste uitvoer met behulp van een uitvoerparameter:
create procedure proc2
@result int OUTPUT
as
select @result = MAX(i) from t where name like 'hello'
go
Hier volgt een voorbeeld van de juiste uitvoer door het uitvoerresultaat een naam te geven:
create procedure proc2
as
begin
select nax(i) AS MaxResult from t where name like 'hello'
end
Zie Bewerkingen aanpassen met behulp van opgeslagen procedures voor meer informatie.
Serialisatiefouten
Wanneer ik probeer te serialiseren, krijg ik de volgende fout: "Type 'System.Data.Linq.ChangeTracker+StandardChangeTracker' ... is niet gemarkeerd als serialiseerbare."
Codegeneratie in LINQ naar SQL ondersteunt DataContractSerializer serialisatie. Het biedt geen ondersteuning XmlSerializer of BinaryFormatter. Zie Serialisatie voor meer informatie.
Meerdere DBML-bestanden
Als ik meerdere DBML-bestanden heb die enkele tabellen gemeen hebben, krijg ik een compilerfout.
Stel de eigenschappen contextnaamruimte en entiteitsnaamruimte van object relationele ontwerper in op een afzonderlijke waarde voor elk DBML-bestand. Deze aanpak elimineert de naam-/naamruimteconflicten.
Expliciete instelling van door database gegenereerde waarden voorkomen bij invoegen of bijwerken
Ik heb een databasetabel met een kolom DateCreated die standaard SQL Getdate()is. Wanneer ik een nieuwe record probeer in te voegen met LINQ naar SQL, wordt de waarde ingesteld op NULL. Ik zou verwachten dat deze is ingesteld op de standaarddatabase.
LINQ naar SQL verwerkt deze situatie automatisch voor identiteiten (automatisch verhogen) en rowguidcol (door database gegenereerde GUID) en tijdstempelkolommen. In andere gevallen moet u handmatig instellen IsDbGeneratedtrue
=enAlways=OnUpdateAutoSync/OnInsert/eigenschappen.
Meerdere DataLoadOptions
Kan ik extra laadopties opgeven zonder de eerste te overschrijven?
Ja. De eerste wordt niet overschreven, zoals in het volgende voorbeeld:
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);
Fouten bij het gebruik van SQL Compact 3.5
Er treedt een fout op wanneer ik tabellen uit een SQL Server Compact 3.5-database sleep.
De object relationele ontwerpfunctie biedt geen ondersteuning voor SQL Server Compact 3.5, hoewel de LINQ naar SQL-runtime dat wel doet. In dit geval moet u uw eigen entiteitsklassen maken en de juiste kenmerken toevoegen.
Fouten in overnamerelaties
Ik heb de overnameshape van de werkset gebruikt in de Object Relational Designer om twee entiteiten te verbinden, maar ik krijg fouten.
Het maken van de relatie is niet voldoende. U moet informatie opgeven, zoals de discriminatorkolom, de discriminatorwaarde van de basisklasse en de afgeleide klassediscriminatorwaarde.
Providermodel
Is er een model voor een openbare provider beschikbaar?
Er is geen model voor openbare providers beschikbaar. Op dit moment ondersteunt LINQ naar SQL Alleen SQL Server en SQL Server Compact 3.5.
SQL-injectieaanvallen
Hoe wordt LINQ naar SQL beveiligd tegen SQL-injectieaanvallen?
SQL-injectie is een aanzienlijk risico geweest voor traditionele SQL-query's die zijn gevormd door het samenvoegen van gebruikersinvoer. LINQ naar SQL voorkomt dergelijke injectie met behulp van SqlParameter query's. Gebruikersinvoer wordt omgezet in parameterwaarden. Met deze methode voorkomt u dat schadelijke opdrachten worden gebruikt vanuit de invoer van de klant.
Alleen-lezen vlag wijzigen in DBML-bestanden
Hoe kan ik setters van bepaalde eigenschappen elimineren wanneer ik een objectmodel maak op basis van een DBML-bestand?
Voer de volgende stappen uit voor dit geavanceerde scenario:
Wijzig de eigenschap in het .dbml-bestand door de IsReadOnly vlag te wijzigen in
True
.Voeg een gedeeltelijke klasse toe. Maak een constructor met parameters voor de alleen-lezen leden.
Controleer de standaardwaarde UpdateCheck (Never) om te bepalen of dit de juiste waarde is voor uw toepassing.
Let op
Als u de Object Relational Designer in Visual Studio gebruikt, worden uw wijzigingen mogelijk overschreven.
APTCA
Is System.Data.Linq gemarkeerd voor gebruik door gedeeltelijk vertrouwde code?
Ja, de System.Data.Linq.dll assembly is een van de .NET Framework-assembly's die zijn gemarkeerd met het AllowPartiallyTrustedCallersAttribute kenmerk. Zonder deze markering zijn assembly's in .NET Framework alleen bedoeld voor gebruik door volledig vertrouwde code.
Het principal-scenario in LINQ naar SQL voor het toestaan van gedeeltelijk vertrouwde aanroepers is dat de LINQ naar SQL-assembly toegankelijk is vanuit webtoepassingen, waarbij de vertrouwensconfiguratie Gemiddeld is.
Toewijzingsgegevens uit meerdere tabellen
De gegevens in mijn entiteit zijn afkomstig uit meerdere tabellen. Hoe kan ik kaart?
U kunt een weergave maken in een database en de entiteit toewijzen aan de weergave. LINQ naar SQL genereert dezelfde SQL voor weergaven als voor tabellen.
Notitie
Het gebruik van weergaven in dit scenario heeft beperkingen. Deze benadering werkt het veiligst wanneer de bewerkingen die worden uitgevoerd Table<TEntity> , worden ondersteund door de onderliggende weergave. Alleen u weet welke bewerkingen zijn bedoeld. De meeste toepassingen zijn bijvoorbeeld alleen-lezen en een ander groot aantal voert alleen bewerkingen uit Create
//Update
Delete
door opgeslagen procedures te gebruiken voor weergaven.
Groepsgewijze verbinding
Is er een constructie die kan helpen bij DataContext-pooling?
Probeer geen exemplaren van DataContext. Elk DataContext onderhoudt de status (inclusief een identiteitscache) voor één bepaalde bewerkings-/querysessie. Als u nieuwe exemplaren wilt verkrijgen op basis van de huidige status van de database, gebruikt u een nieuwe DataContext.
U kunt nog steeds onderliggende ADO.NET groepsgewijze verbindingen gebruiken. Zie SQL Server Verbinding maken ion Pooling (ADO.NET) voor meer informatie.
Second DataContext Is Not Updated
Ik heb één exemplaar van DataContext gebruikt om waarden in de database op te slaan. Een tweede DataContext in dezelfde database geeft echter niet de bijgewerkte waarden weer. Het tweede DataContext-exemplaar lijkt waarden in de cache te retourneren.
Dit is zo ontworpen. LINQ naar SQL blijft dezelfde exemplaren/waarden retourneren die u in het eerste exemplaar hebt gezien. Wanneer u updates aanbrengt, gebruikt u optimistische gelijktijdigheid. De oorspronkelijke gegevens worden gebruikt om te controleren op basis van de huidige databasestatus om te bevestigen dat deze in feite nog steeds ongewijzigd zijn. Als dit is gewijzigd, treedt er een conflict op en moet uw toepassing dit oplossen. Een van de opties van uw toepassing is om de oorspronkelijke status opnieuw in te stellen op de huidige databasestatus en de update opnieuw uit te voeren. Zie Voor meer informatie : Wijzigingsconflicten beheren.
U kunt ook instellen ObjectTrackingEnabled op onwaar, waardoor caching en wijzigingen bijhouden worden uitgeschakeld. Vervolgens kunt u de meest recente waarden ophalen telkens wanneer u een query uitvoert.
Kan SubmitChanges niet aanroepen in de modus Alleen-lezen
Wanneer ik SubmitChanges probeer aan te roepen in de modus Alleen-lezen, krijg ik een foutmelding.
De modus Alleen-lezen schakelt de mogelijkheid van de context uit om wijzigingen bij te houden.