SQL-CLR-Typenzuordnung

In LINQ to SQL wird das Datenmodell einer relationalen Datenbank einem Objektmodell zugeordnet, das in einer beliebigen Programmiersprache erstellt wurde. Bei der Ausführung der Anwendung wandelt LINQ to SQL die sprachintegrierten Abfragen im Objektmodell in SQL um und sendet sie zur Ausführung an die Datenbank. Wenn die Datenbank die Ergebnisse zurückgibt, übersetzt LINQ to SQL diese zurück in Objekte, mit denen in einer Programmiersprache gearbeitet werden kann.

Damit Daten zwischen dem Objektmodell und der Datenbank übertragen werden können, muss eine Typzuordnung (Typmapping) definiert werden. Mithilfe des Typmappings stellt LINQ to SQL eine Zuordnung zwischen jedem Typ der CLR (Common Language Runtime) und einem bestimmten SQL Server-Typ her. Die Typmappings und andere Mappinginformationen, wie Datenbankstrukturen und Tabellenbeziehungen, können im Objektmodell mithilfe von attributbasiertem Mapping definiert werden. Alternativ dazu können die Mappinginformationen außerhalb des Objektmodells mit einer externen Mappingdatei festgelegt werden. Weitere Informationen finden Sie unter Attributbasierte Zuordnung und Externe Zuordnung.

In diesem Thema werden folgende Punkte erläutert:

Standardtypmapping

Das Objektmodell oder die externe Mappingdatei kann mithilfe des objektrelationalen Designers (O/R-Designer) oder mit dem Befehlszeilentool SQLMetal automatisch erstellt werden. Durch Standardtypmappings für diese Tools wird festgelegt, welche CLR-Typen bestimmten Spalten in der SQL Server-Datenbank zugeordnet werden sollen. Weitere Informationen zur Verwendung dieser Tools finden Sie unter Erstellen des Objektmodells.

Mithilfe der CreateDatabase-Methode kann weiterhin eine SQL Server-Datenbank auf Grundlage der Mappinginformationen des Objektmodells oder der externen Mappingdatei erstellt werden. Mit den Standardtypmappings für die CreateDatabase-Methode wird festgelegt, welche Typen von SQL Server-Spalten für das Mapping der CLR-Typen im Objektmodell erstellt werden. Weitere Informationen finden Sie unter Gewusst wie: Dynamisches Erstellen einer neuen Datenbank.

Laufzeitverhaltens-Matrix des Typmappings

In der folgenden Grafik wird das erwartete Laufzeitverhalten spezifischer Typmappings dargestellt, wenn Daten von der Datenbank abgerufen oder in ihr gespeichert werden. Mit Ausnahme der Serialisierung unterstützt LINQ to SQL kein Mapping zwischen CLR- oder SQL Server-Datentypen, die nicht in dieser Matrix aufgeführt sind. Weitere Informationen zur Unterstützung der Serialisierung finden Sie unter Binäre Serialisierung.

SQL Server to SQL CLR data type mapping table

Hinweis

Einige Typmappings können bei der Übertragung in die Datenbank oder aus der Datenbank einen Überlauf oder Datenverlust verursachen.

Benutzerdefinierte Typzuordnung

Mit LINQ to SQL sind die Standardtypmappings nicht auf diejenigen beschränkt, die von O/R-Designer, SQLMetal und der CreateDatabase-Methode verwendet werden. Sie können benutzerdefinierte Typmappings erstellen, indem Sie sie explizit in einer DBML-Datei angeben. Mit dieser DBML-Datei können Sie danach den Objektmodellcode und die Mappingdatei erstellen. Weitere Informationen finden Sie unter Benutzerdefinierte SQL-CLR-Typenzuordnungen.

Verhaltensunterschiede zwischen CLR- und SQL-Ausführung

Aufgrund der Unterschiede bezüglich Präzision und Ausführung zwischen der CLR und SQL Server können Berechnungen zu unterschiedlichen Ergebnissen und unterschiedlichem Verhalten führen. Berechnungen, die in LINQ to SQL-Abfragen ausgeführt wurden, werden erst in Transact-SQL übersetzt und dann für die SQL Server-Datenbank ausgeführt. Außerhalb von LINQ to SQL-Abfragen ausgeführte Berechnungen werden im Kontext der CLR ausgeführt.

Folgende Beispiele zeigen einige Unterschiede im Verhalten zwischen der CLR und SQL Server:

  • In SQL Server und der CLR werden verschiedene vergleichbare Datentypen unterschiedlich sortiert. Zum Beispiel werden SQL Server-Daten des Typs UNIQUEIDENTIFIER anders sortiert als CLR-Daten des Typs System.Guid.

  • SQL Server behandelt verschiedene Vorgänge für Zeichenfolgenvergleiche anders als die CLR. In SQL Server ist das Verhalten bei Zeichenfolgenvergleichen von den Sortierungseinstellungen auf dem Server abhängig. Weitere Informationen finden Sie unter Arbeiten mit Sortierungen.

  • Für einige zugeordnete Funktionen werden von SQL Server andere Werte zurückgegeben als von der CLR. Die Funktionen für die Überprüfung auf Gleichheit beispielsweise unterscheiden sich, da von SQL Server zwei Zeichenketten als gleich aufgefasst werden, wenn sie sich lediglich durch nachgestellte Leerzeichen unterscheiden, während solche Zeichenketten von der CLR als unterschiedlich aufgefasst werden.

Enumerationsmapping

LINQ to SQL unterstützt für das Mapping des CLR-System.Enum-Typs zu SQL Server-Typen zwei Arten:

  • Zuordnung zu numerischen SQL-Typen (TINYINT, SMALLINT, INT, BIGINT)

    Wenn ein CLR-System.Enum-Typ einem numerischen SQL-Typ zugeordnet wird, wird der zugrunde liegende CLR-System.Enum-Typ dem Wert der SQL Server-Datenbankspalte zugeordnet. Enthält z. B. ein System.Enum mit dem Namen DaysOfWeek einen Member mit dem Namen Tue und dem zugrunde liegenden Ganzzahlwert 3, wird dieser dem Datenbankwert 3 zugeordnet.

  • Zuordnung zu SQL-Texttypen (CHAR, NCHAR, VARCHAR, NVARCHAR)

    Wenn ein CLR-System.Enum-Typ einem SQL-Texttyp zugeordnet wird, wird der SQL-Datenbankwert den Namen der CLR-System.Enum-Member zugeordnet. Enthält z. B. ein System.Enum mit dem Namen DaysOfWeek einen Member mit dem Namen Tue und dem zugrunde liegenden Ganzzahlwert 3, wird dieser dem Datenbankwert Tue zugeordnet.

Hinweis

Beim Mapping von SQL-Texttypen zu einer CLR-System.Enum sollten nur die Namen der Enum-Member in der zugeordneten SQL-Spalte enthalten sein. Andere Werte werden in der der Enum zugeordneten SQL-Spalte nicht unterstützt.

Mit dem O/R-Designer und dem SQLMetal-Befehlszeilentool kann ein SQL-Typ nicht automatisch einer CLR-Enum-Klasse zugeordnet werden. Sie müssen diese Zuordnung explizit konfigurieren, indem Sie eine DBML-Datei zur Verwendung mit dem O/R-Designer und SQLMetal anpassen. Weitere Informationen zur benutzerdefinierten Typzuordnung finden Sie unter Benutzerdefinierte SQL-CLR-Typenzuordnungen.

Da eine SQL-Spalte für eine Enumeration vom gleichen Typ wie andere numerische Spalten und Textspalten ist, erkennen diese Tools die Absicht nicht und führen standardmäßig die in den Abschnitten Numerisches Mapping und Text- und XML-Mapping beschriebene Zuordnung aus. Weitere Informationen zum Generieren von Code mit der DBML-Datei finden Sie unter Codegenerierung in LINQ to SQL.

Die DataContext.CreateDatabase-Methode erstellt eine SQL-Spalte eines numerischen Typs zum Mapping eines CLR-System.Enum-Typs.

Numerisches Mapping

Mit LINQ to SQL können viele numerische CLR- und SQL Server-Typen zugeordnet werden. Die Tabelle enthält auch die CLR-Typen, die von O/R-Designer und SQLMetal für die auf einer bestehenden Datenbank basierende Erstellung eines Objektmodells oder einer externen Mappingdatei ausgewählt werden.

SQL Server-Typ Von O/R-Designer und SQLMetal verwendetes CLR-Standardtypmapping
BIT System.Boolean
TINYINT System.Int16
INT System.Int32
BIGINT System.Int64
SMALLMONEY System.Decimal
MONEY System.Decimal
DECIMAL System.Decimal
NUMERIC System.Decimal
REAL/FLOAT(24) System.Single
FLOAT/FLOAT(53) System.Double

In der nächsten Tabelle werden die Standardtypmappings angezeigt, die von der DataContext.CreateDatabase-Methode verwendet werden, um festzulegen, welche Typen von SQL-Spalten für die Zuordnung zu den im Objektmodell oder der externen Mappingdatei definierten CLR-Typen erstellt werden.

CLR-Typ Von DataContext.CreateDatabase verwendeter Standard-SQL Server-Typ
System.Boolean BIT
System.Byte TINYINT
System.Int16 SMALLINT
System.Int32 INT
System.Int64 BIGINT
System.SByte SMALLINT
System.UInt16 INT
System.UInt32 BIGINT
System.UInt64 DECIMAL(20)
System.Decimal DECIMAL(29,4)
System.Single REAL
System.Double FLOAT

Es können viele andere numerische Mappings ausgewählt werden. Einige davon können jedoch bei der Übertragung in die Datenbank oder aus der Datenbank einen Überlauf oder Datenverlust verursachen. Weitere Informationen finden Sie unter Laufzeitverhaltens-Matrix des Typmappings.

Dezimal- und Währungstypen

Die Standardgenauigkeit des SQL Server-Typs DECIMAL (18 Dezimalstellen links und rechts vom Dezimalpunkt) ist wesentlich geringer als die Genauigkeit des standardmäßig zugeordneten CLR-Typs System.Decimal. Dies kann beim Speichern von Daten in der Datenbank zu Genauigkeitsverlust führen. Umgekehrt kann jedoch das gleiche auftreten, wenn der SQL Server-Typ DECIMAL für eine Genauigkeit von mehr als 29 Stellen konfiguriert ist. Wenn der SQL Server-Typ DECIMAL für eine höhere Genauigkeit konfiguriert ist als der CLR-Typ System.Decimal, kann Genauigkeitsverlust beim Abrufen von Daten aus der Datenbank auftreten.

Die SQL Server-Typen MONEY und SMALLMONEY, die standardmäßig ebenfalls dem CLR-Typ System.Decimal zugeordnet werden, haben eine niedrigere Genauigkeit. Dies kann beim Speichern von Daten in der Datenbank einen Überlauf oder Datenverlust verursachen.

Text- und XML-Mapping

Es gibt viele textbasierte Typen und XML-Typen, die mit LINQ to SQL zugeordnet werden können. Die Tabelle enthält auch die CLR-Typen, die von O/R-Designer und SQLMetal für die auf einer bestehenden Datenbank basierende Erstellung eines Objektmodells oder einer externen Mappingdatei ausgewählt werden.

SQL Server-Typ Von O/R-Designer und SQLMetal verwendetes CLR-Standardtypmapping
CHAR System.String
NCHAR System.String
VARCHAR System.String
NVARCHAR System.String
TEXT System.String
NTEXT System.String
XML System.Xml.Linq.XElement

In der nächsten Tabelle werden die Standardtypmappings angezeigt, die von der DataContext.CreateDatabase-Methode verwendet werden, um festzulegen, welche Typen von SQL-Spalten für die Zuordnung zu den im Objektmodell oder der externen Mappingdatei definierten CLR-Typen erstellt werden.

CLR-Typ Von DataContext.CreateDatabase verwendeter Standard-SQL Server-Typ
System.Char NCHAR(1)
System.String NVARCHAR(4000)
System.Char[] NVARCHAR(4000)
Benutzerdefinierter Typ, mit dem Parse() und ToString() implementiert werden. NVARCHAR(MAX)

Es können viele andere textbasierte und XML-Mappings ausgewählt werden. Einige davon können jedoch bei der Übertragung in die Datenbank oder aus der Datenbank einen Überlauf oder Datenverlust verursachen. Weitere Informationen finden Sie unter Laufzeitverhaltens-Matrix des Typmappings.

XML-Typen

Der XML-Datentyp von SQL Server ist seit Microsoft SQL Server 2005 verfügbar. Der XML-Datentyp von SQL Server kann XElement, XDocument oder String zugeordnet werden. Wenn die Spalte XML-Fragmente speichert, die nicht in XElement eingelesen werden können, muss die Spalte String zugeordnet werden, um Laufzeitfehler zu vermeiden. Zu den XML-Fragmenten, die String zugeordnet werden müssen, zählen die folgenden:

  • Eine Sequenz von XML-Elementen

  • Attribute

  • Öffentliche Bezeichner (Public Identifier, PI)

  • Kommentare

Obwohl XElement und XDocument, wie in der Laufzeitverhaltens-Matrix des Typmappings dargestellt, SQL Server zugeordnet werden können, verfügt die DataContext.CreateDatabase-Methode nicht über eine Standard-SQL Server-Typzuordnung für diese Typen.

Benutzerdefinierte Typen

Wenn eine Klasse Parse() und ToString() implementiert, können Sie das Objekt einem beliebigen SQL-Texttyp (CHAR, NCHAR, VARCHAR, NVARCHAR, TEXT, NTEXT, XML) zuordnen. Das Objekt wird in der Datenbank gespeichert, indem der von ToString() zurückgegebene Wert in der zugeordneten Datenbankspalte gespeichert wird. Das Objekt wird rekonstruiert, indem Parse() für die von der Datenbank zurückgegebene Zeichenfolge aufgerufen wird.

Hinweis

LINQ to SQL unterstützt keine Serialisierung mithilfe von System.Xml.Serialization.IXmlSerializable.

Datums- und Uhrzeitmapping

Mit LINQ to SQL können viele SQL Server-Datums- und Uhrzeittypen zugeordnet werden. Die Tabelle enthält auch die CLR-Typen, die von O/R-Designer und SQLMetal für die auf einer bestehenden Datenbank basierende Erstellung eines Objektmodells oder einer externen Mappingdatei ausgewählt werden.

SQL Server-Typ Von O/R-Designer und SQLMetal verwendetes CLR-Standardtypmapping
SMALLDATETIME System.DateTime
DATETIME System.DateTime
DATETIME2 System.DateTime
DATETIMEOFFSET System.DateTimeOffset
DATE System.DateTime
TIME System.TimeSpan

In der nächsten Tabelle werden die Standardtypmappings angezeigt, die von der DataContext.CreateDatabase-Methode verwendet werden, um festzulegen, welche Typen von SQL-Spalten für die Zuordnung zu den im Objektmodell oder der externen Mappingdatei definierten CLR-Typen erstellt werden.

CLR-Typ Von DataContext.CreateDatabase verwendeter Standard-SQL Server-Typ
System.DateTime DATETIME
System.DateTimeOffset DATETIMEOFFSET
System.TimeSpan TIME

Es können viele andere Datums- und Uhrzeitmappings ausgewählt werden. Einige davon können jedoch bei der Übertragung in die Datenbank oder aus der Datenbank einen Überlauf oder Datenverlust verursachen. Weitere Informationen finden Sie unter Laufzeitverhaltens-Matrix des Typmappings.

Hinweis

Die SQL Server-Typen DATETIME2, DATETIMEOFFSET, DATE und TIME sind seit Microsoft SQL Server 2008 verfügbar. LINQ to SQL unterstützt das Mapping dieser neuen Typen seit .NET Framework, Version 3.5, SP1.

System.DateTime

Der Bereich und die Genauigkeit des CLR-Typs System.DateTime sind größer als der Bereich und die Genauigkeit des SQL Server-Typs DATETIME. Diese beiden Typen werden mit dem Standardtypmapping der DataContext.CreateDatabase-Methode einander zugeordnet. Um Ausnahmen im Zusammenhang mit außerhalb des Bereichs von DATETIME liegenden Datumswerten zu vermeiden, sollte der seit Microsoft SQL Server 2008 verfügbare DATETIME2-Typ verwendet werden. DATETIME2 kann an den Bereich und die Genauigkeit des CLR-Typs System.DateTime angeglichen werden.

SQL Server-Datumswerte unterstützen keine TimeZone, eine Funktion, die in der CLR große Bedeutung hat. TimeZone-Werte werden ohne TimeZone-Umwandlung in der Datenbank gespeichert, unabhängig von den ursprünglichen DateTimeKind-Informationen. Werden DateTime-Werte aus der Datenbank abgerufen, werden diese wie in DateTime mit einer DateTimeKind von Unspecified geladen. Weitere Informationen zu unterstützten System.DateTime-Methoden finden Sie unter System.DateTime-Methoden.

System.TimeSpan

Mit Microsoft SQL Server 2008 und .NET Framework 3.5 SP1 kann der CLR-Typ System.TimeSpan dem SQL Server-Typ TIME zugeordnet werden. Es gibt jedoch große Unterschiede im von dem CLR-Typ System.TimeSpan und dem SQL Server-Typ TIME unterstützten Bereich. Das Mapping von Stundenwerten kleiner als 0 oder größer als 23:59:59.9999999 zum SQL-Typ TIME hat Überlaufausnahmen zur Folge. Weitere Informationen finden Sie unter System.TimeSpan-Methoden.

In Microsoft SQL Server 2000 und SQL Server 2005 können TimeSpan keine Datenbankfelder zugeordnet werden. Dennoch werden Operationen für TimeSpan unterstützt, da TimeSpan-Werte von DateTime-Subtraktionen zurückgegeben oder als Literal oder gebundene Variable in einen Ausdruck integriert werden können.

Binäres Mapping

Es gibt mehrere SQL Server-Typen, die dem CLR-Typ System.Data.Linq.Binary zugeordnet werden können. In der folgenden Tabelle sind die SQL Server-Typen aufgeführt, für die von O/R-Designer und SQLMetal für die auf einer bestehenden Datenbank basierende Erstellung eines Objektmodells oder einer externen Mappingdatei der CLR-Typ System.Data.Linq.Binary definiert wird.

SQL Server-Typ Von O/R-Designer und SQLMetal verwendetes CLR-Standardtypmapping
BINARY(50) System.Data.Linq.Binary
VARBINARY(50) System.Data.Linq.Binary
VARBINARY(MAX) System.Data.Linq.Binary
VARBINARY(MAX) mit dem FILESTREAM-Attribut System.Data.Linq.Binary
IMAGE System.Data.Linq.Binary
TIMESTAMP System.Data.Linq.Binary

In der nächsten Tabelle werden die Standardtypmappings angezeigt, die von der DataContext.CreateDatabase-Methode verwendet werden, um festzulegen, welche Typen von SQL-Spalten für die Zuordnung zu den im Objektmodell oder der externen Mappingdatei definierten CLR-Typen erstellt werden.

CLR-Typ Von DataContext.CreateDatabase verwendeter Standard-SQL Server-Typ
System.Data.Linq.Binary VARBINARY(MAX)
System.Byte VARBINARY(MAX)
System.Runtime.Serialization.ISerializable VARBINARY(MAX)

Es können viele andere binäre Mappings ausgewählt werden. Einige davon können jedoch bei der Übertragung in die Datenbank oder aus der Datenbank einen Überlauf oder Datenverlust verursachen. Weitere Informationen finden Sie unter Laufzeitverhaltens-Matrix des Typmappings.

SQL Server FILESTREAM

Das FILESTREAM-Attribut für VARBINARY(MAX)-Spalten ist seit Microsoft SQL Server 2008 verfügbar. Dieses Attribut kann ab .NET Framework Version 3.5 SP1 mit LINQ to SQL zugeordnet werden.

Obwohl VARBINARY(MAX)-Spalten mit dem FILESTREAM-Attribut Binary-Objekten zugeordnet werden können, können von der DataContext.CreateDatabase-Methode keine Spalten mit dem FILESTREAM-Attribut automatisch erstellt werden. Weitere Informationen zu FILESTREAM finden Sie unter Übersicht über FILESTREAM.

Binäre Serialisierung

Wenn eine Klasse die ISerializable-Schnittstelle implementiert, kann ein Objekt in ein beliebiges binäres SQL-Feld (BINARY, VARBINARY, IMAGE) serialisiert werden. Das Objekt wird je nach Implementierung der ISerializable-Schnittstelle serialisiert und deserialisiert. Weitere Informationen finden Sie unter Binäre Serialisierung.

Verschiedene Mappingtypen

In der folgenden Tabelle sind die Standardtypmappings für verschiedene Typen aufgeführt, die noch nicht erwähnt wurden. Die Tabelle enthält auch die CLR-Typen, die von O/R-Designer und SQLMetal für die auf einer bestehenden Datenbank basierende Erstellung eines Objektmodells oder einer externen Mappingdatei ausgewählt werden.

SQL Server-Typ Von O/R-Designer und SQLMetal verwendetes CLR-Standardtypmapping
UNIQUEIDENTIFIER System.Guid
SQL_VARIANT System.Object

In der nächsten Tabelle werden die Standardtypmappings angezeigt, die von der DataContext.CreateDatabase-Methode verwendet werden, um festzulegen, welche Typen von SQL-Spalten für die Zuordnung zu den im Objektmodell oder der externen Mappingdatei definierten CLR-Typen erstellt werden.

CLR-Typ Von DataContext.CreateDatabase verwendeter Standard-SQL Server-Typ
System.Guid UNIQUEIDENTIFIER
System.Object SQL_VARIANT

LINQ to SQL unterstützt keine anderen Typmappings für diese Typen. Weitere Informationen finden Sie unter Laufzeitverhaltens-Matrix des Typmappings.

Weitere Informationen