Následující části odpovídají na některé běžné problémy, se kterými se můžete setkat při implementaci LINQ.
Další problémy jsou vyřešeny v řešení potíží.
Nejde Připojení
Nemůžu se připojit k databázi.
Ujistěte se, že je váš připojovací řetězec správný a že je spuštěná instance SQL Serveru. Všimněte si také, že LINQ to SQL vyžaduje povolení protokolu Pojmenované kanály. Další informace najdete v tématu Učení návody.
Změny v databázi byly ztraceny.
Provedl(a) jsem změnu dat v databázi, ale když jsem aplikaci znovu našel, změna už tam nebyla.
Ujistěte se, že voláte SubmitChanges , abyste uložili výsledky do databáze.
Připojení ion databáze: Otevřete jak dlouho?
Jak dlouho zůstane připojení k databázi otevřené?
Připojení obvykle zůstane otevřené, dokud nespotřebujete výsledky dotazu. Pokud očekáváte, že zpracování všech výsledků nějakou dobu trvá a nejsou na rozdíl od ukládání výsledků do mezipaměti, použijte ToList je u dotazu. V běžných scénářích, kdy se každý objekt zpracovává pouze jednou, je model streamování vynikající v DataReader
jazyce LINQ to SQL.
Přesné podrobnosti o využití připojení závisí na následujících:
Připojení stav, DataContext pokud je vytvořen s objektem připojení.
Připojení nastavení řetězce (například povolení více aktivních sad výsledků (MARS). Další informace naleznete v tématu Více aktivních sad výsledků (MARS).
Aktualizace bez dotazování
Můžu aktualizovat data tabulky bez prvního dotazování databáze?
I když LINQ to SQL neobsahuje příkazy aktualizace založené na sadě, můžete k aktualizaci bez prvního dotazování použít některý z následujících technik:
Slouží ExecuteCommand k odesílání kódu SQL.
Vytvořte novou instanci objektu a inicializujete všechny aktuální hodnoty (pole), které ovlivňují aktualizaci. Pak objekt připojte k objektu DataContext pomocí Attach a upravte pole, které chcete změnit.
Neočekávané výsledky dotazu
Dotaz vrací neočekávané výsledky. Jak můžu zkontrolovat, co se děje?
LINQ to SQL poskytuje několik nástrojů pro kontrolu kódu SQL, který generuje. Jedním z nejdůležitějších je Log. Další informace naleznete v tématu Podpora ladění.
Neočekávané výsledky uložené procedury
Mám uloženou proceduru, jejíž návratová hodnota je vypočítána parametrem MAX(). Když přetáhnem uloženou proceduru na plochu Návrháře relací objektů, návratová hodnota není správná.
LINQ to SQL nabízí dva způsoby vrácení hodnot generovaných databází pomocí uložených procedur:
Pojmenováním výsledku výstupu.
Explicitním zadáním výstupního parametru
Následuje příklad nesprávného výstupu. Vzhledem k tomu, že LINQ to SQL nemůže namapovat výsledky, vrátí vždy hodnotu 0:
create procedure proc2
as
begin
select max(i) from t where name like 'hello'
end
Následuje příklad správného výstupu pomocí výstupního parametru:
create procedure proc2
@result int OUTPUT
as
select @result = MAX(i) from t where name like 'hello'
go
Následuje příklad správného výstupu pojmenováním výsledku výstupu:
create procedure proc2
as
begin
select nax(i) AS MaxResult from t where name like 'hello'
end
Další informace naleznete v tématu Přizpůsobení operací pomocí uložených procedur.
Chyby serializace
Při pokusu o serializaci se zobrazí následující chyba: "Type 'System.Data.Linq.ChangeTracker+StandardChangeTracker' ... není označena jako serializovatelná."
Generování kódu v LINQ to SQL podporuje DataContractSerializer serializaci. Nepodporuje XmlSerializer ani BinaryFormatter. Další informace naleznete v tématu Serializace.
Více souborů DBML
Když mám více souborů DBML, které sdílejí některé tabulky běžně, zobrazí se chyba kompilátoru.
Nastavte vlastnosti oboru názvů kontextu a oboru názvů entity z Návrhář relací objektů na jedinečnou hodnotu pro každý soubor DBML. Tento přístup eliminuje kolize názvů a oborů názvů.
Vyhněte se explicitnímu nastavení hodnot generovaných databází při vložení nebo aktualizaci.
Mám tabulku databáze se sloupcem DateCreated, který má výchozí hodnotu SQL Getdate(). Při pokusu o vložení nového záznamu pomocí LINQ to SQL se hodnota nastaví na NULL. Očekával bych, že bude nastavena na výchozí hodnotu databáze.
LINQ to SQL zpracovává tuto situaci automaticky pro sloupce identity (automatického přírůstku) a rowguidcol (guid generovaného databází) a časového razítka. V jiných případech byste měli ručně nastavit IsDbGeneratedtrue
=aAlways=OnUpdateAutoSync/OnInsert/nastavit vlastnosti.
Více datových částí
Můžu zadat další možnosti načtení bez přepsání prvního?
Ano. První není přepsán, jak je znázorněno v následujícím příkladu:
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);
Chyby při používání SQL Compact 3.5
Při přetažení tabulek z databáze SQL Server Compact 3.5 se zobrazí chyba.
Návrhář relací objektů nepodporuje SQL Server Compact 3.5, i když modul runtime LINQ to SQL. V této situaci musíte vytvořit vlastní třídy entit a přidat příslušné atributy.
Chyby v relacích dědičnosti
Použil(a) jsem tvar dědičnosti panelu nástrojů v Návrhář relací objektů k propojení dvou entit, ale dochází k chybám.
Vytvoření relace nestačí. Musíte zadat informace, jako je například nediskriminační sloupec, diskriminátor základní třídy a diskriminující hodnota odvozené třídy.
Model zprostředkovatele
Je k dispozici model veřejného poskytovatele?
Není k dispozici žádný model veřejného poskytovatele. V tuto chvíli LINQ to SQL podporuje pouze SQL Server a SQL Server Compact 3.5.
Útoky prostřednictvím injektáže SQL
Jak je LINQ to SQL chráněné před útoky prostřednictvím injektáže SQL?
Injektáž SQL představuje významné riziko pro tradiční dotazy SQL vytvořené zřetězením uživatelského vstupu. LINQ to SQL se takovým injektážem SqlParameter v dotazech vyhne. Uživatelský vstup je převeden na hodnoty parametrů. Tento přístup brání použití škodlivých příkazů ze vstupu zákazníka.
Změna příznaku jen pro čtení v souborech DBML
Návody eliminovat settery z některých vlastností při vytváření objektového modelu ze souboru DBML?
Pro tento pokročilý scénář proveďte následující kroky:
V souboru .dbml upravte vlastnost změnou příznaku IsReadOnly na
True
.Přidejte částečnou třídu. Vytvořte konstruktor s parametry pro členy jen pro čtení.
Zkontrolujte výchozí UpdateCheck hodnotu (Never) a zjistěte, jestli je to správná hodnota pro vaši aplikaci.
Upozornění
Pokud používáte Návrhář relací objektů v sadě Visual Studio, můžou se změny přepsat.
APTCA
Je System.Data.Linq označený pro použití částečně důvěryhodným kódem?
Ano, sestavení System.Data.Linq.dll patří mezi sestavení rozhraní .NET Framework označená atributem AllowPartiallyTrustedCallersAttribute . Bez tohoto označení jsou sestavení v rozhraní .NET Framework určena pouze plně důvěryhodným kódem.
Hlavním scénářem linQ to SQL pro povolení částečně důvěryhodných volajících je umožnit přístup k sestavení LINQ to SQL z webových aplikací, kde konfigurace důvěryhodnosti je Střední.
Mapování dat z více tabulek
Data v mé entitě pocházejí z více tabulek. Návody to namapovat?
V databázi můžete vytvořit zobrazení a namapovat entitu na zobrazení. LINQ to SQL generuje stejné SQL pro zobrazení jako u tabulek.
Poznámka:
Použití zobrazení v tomto scénáři má omezení. Tento přístup funguje nejbezpečněji, když jsou operace prováděné Table<TEntity> v podkladovém zobrazení podporovány. Jen víte, které operace jsou určené. Například většina aplikací je jen pro čtení a jiné číslo s velikostí provádí Create
//Update
Delete
operace pouze pomocí uložených procedur s zobrazeními.
Sdružování připojení
Existuje konstruktor, který může pomoct s sdružováním dat DataContext?
Nepokoušejte se opakovaně používat instance .DataContext Každý DataContext udržuje stav (včetně mezipaměti identit) pro jednu konkrétní relaci úprav a dotazů. Chcete-li získat nové instance na základě aktuálního stavu databáze, použijte nový DataContext.
Stále můžete použít základní ADO.NET sdružování připojení. Další informace naleznete v tématu SQL Server Připojení sdružování (ADO.NET).
Druhý text DataContext se neaktualizuje.
Použil(a) jsem jednu instanci DataContext k ukládání hodnot v databázi. Druhý objekt DataContext ve stejné databázi však neodráží aktualizované hodnoty. Zdá se, že druhá instance DataContext vrací hodnoty uložené v mezipaměti.
Toto chování je záměrné. LINQ to SQL nadále vrací stejné instance a hodnoty, které jste viděli v první instanci. Při provádění aktualizací použijete optimistickou souběžnost. Původní data se používají ke kontrole aktuálního stavu databáze, aby se ověřilo, že se ve skutečnosti nezměnila. Pokud došlo ke změně, dojde ke konfliktu a vaše aplikace ji musí vyřešit. Jednou z možností vaší aplikace je resetovat původní stav do aktuálního stavu databáze a zkusit aktualizaci zopakovat. Další informace naleznete v tématu Postupy: Správa konfliktů změn.
Můžete také nastavit ObjectTrackingEnabled hodnotu False, která vypne ukládání do mezipaměti a sledování změn. Při každém dotazování pak můžete načíst nejnovější hodnoty.
Nejde volat SubmitChanges v režimu jen pro čtení
Při pokusu o volání SubmitChanges v režimu jen pro čtení se zobrazí chyba.
Režim jen pro čtení vypne schopnost kontextu sledovat změny.