Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
LINQ to SQL unterstützt die Bindung an allgemeine Steuerelemente, z. B. Rastersteuerelemente. Insbesondere definiert LINQ to SQL die grundlegenden Muster für die Bindung an ein Datenraster und die Verarbeitung von Master-Detail-Bindung sowohl im Hinblick auf die Anzeige als auch die Aktualisierung.
Zugrunde liegendes Prinzip
LINQ to SQL übersetzt LINQ-Abfragen für die Ausführung in einer Datenbank in SQL. Die Ergebnisse sind IEnumerable
mit strikter Typbindung. Da es sich bei diesen Objekten um gewöhnliche CLR-Objekte (Common Language Runtime) handelt, können gewöhnliche Objektdatenbindungen verwendet werden, um die Ergebnisse anzuzeigen. Andererseits erfordern Änderungsvorgänge (Einfügungen, Aktualisierungen und Löschvorgänge) zusätzliche Schritte.
Vorgang
Die implizite Bindung an Windows Forms-Steuerelemente erfolgt durch das Implementieren IListSource. Generische Datenquellen Table<TEntity> (Table<T>
in C# oder Table(Of T)
in Visual Basic) und generische DataQuery
wurden aktualisiert, um IListSource zu implementieren. Benutzeroberflächen-Datenbindungsmodule (Windows Forms und Windows Presentation Foundation) testen jeweils, ob ihre Datenquelle IListSource implementiert. Daher ruft das direkte Zuweisen einer Abfrage an eine Datenquelle eines Steuerelements implizit eine LINQ-to-SQL-Auflistungserstellung auf, wie im folgenden Beispiel gezeigt:
DataGrid dataGrid1 = new DataGrid();
DataGrid dataGrid2 = new DataGrid();
DataGrid dataGrid3 = new DataGrid();
var custQuery =
from cust in db.Customers
select cust;
dataGrid1.DataSource = custQuery;
dataGrid2.DataSource = custQuery;
dataGrid2.DataMember = "Orders";
BindingSource bs = new BindingSource();
bs.DataSource = custQuery;
dataGrid3.DataSource = bs;
Dim dataGrid1 As New DataGrid()
Dim dataGrid2 As New DataGrid()
Dim dataGrid3 As New DataGrid()
Dim custQuery = _
From cust In db.Customers _
Select cust
dataGrid1.DataSource = custQuery
dataGrid2.DataSource = custQuery
dataGrid2.DataMember = "Orders"
Dim bs = _
New BindingSource()
bs.DataSource = custQuery
dataGrid3.DataSource = bs
Dasselbe geschieht mit Windows Presentation Foundation:
ListView listView1 = new ListView();
var custQuery2 =
from cust in db.Customers
select cust;
ListViewItem ItemsSource = new ListViewItem();
ItemsSource = (ListViewItem)custQuery2;
Dim listView1 As New ListView()
Dim custQuery2 = _
From cust In db.Customers _
Select cust
Dim ItemsSource As New ListViewItem
ItemsSource = custQuery2
Auflistungsgenerierungen werden von generischem Table<TEntity> und generischem DataQuery
in GetList implementiert.
IListSource-Implementierung
LINQ to SQL implementiert IListSource an zwei Stellen:
Die Datenquelle ist eine Table<TEntity>: LINQ to SQL durchsucht die Tabelle, um eine
DataBindingList
Auflistung auszufüllen, die einen Verweis auf die Tabelle behält.Die Datenquelle ist eine IQueryable<T>. Es gibt zwei Szenarien:
Findet LINQ to SQL die zugrunde liegende Table<TEntity> in der IQueryable<T>, ermöglicht die Quelle das Bearbeiten, und die Situation entspricht jener im ersten Listenpunkt.
Wenn LINQ to SQL den zugrunde liegenden Table<TEntity> nicht finden kann, lässt die Quelle keine Bearbeitung zu (z. B.
groupby
). LINQ to SQL durchsucht die Abfrage, um ein generischesSortableBindingList
auszufüllen, das ein einfaches BindingList<T> ist und das Sortierfeature für T-Entitäten in Bezug auf eine bestimmte Eigenschaft implementiert.
Spezialisierte Sammlungen
Für viele Features, die weiter oben in diesem Dokument beschrieben wurden, wurde BindingList<T> auf einige verschiedene Klassen spezialisiert. Diese Klassen sind generisch SortableBindingList
und generisch DataBindingList
. Beide werden als intern deklariert.
Generische SortableBindingList
Diese Klasse erbt von BindingList<T>, und ist eine sortierbare Version von BindingList<T>. Beim Sortieren handelt es sich um eine Speicherlösung, die niemals die Datenbank selbst kontaktiert.
BindingList<T> implementiert IBindingList , unterstützt jedoch die Sortierung nicht standardmäßig.
BindingList<T> Implementiert IBindingList jedoch mit virtuellen Kernmethoden. Sie können diese Methoden leicht überschreiben. Die generische SortableBindingList
überschreibt SupportsSortingCore, SortPropertyCore, SortDirectionCore und ApplySortCore.
ApplySortCore
wird aufgerufen und ApplySort sortiert die Liste der T-Elemente für eine bestimmte Eigenschaft.
Wenn die Eigenschaft nicht zu T gehört, wird eine Ausnahme ausgelöst.
Um die Sortierung zu erreichen, erstellt LINQ to SQL eine generische SortableBindingList.PropertyComparer
Klasse, die von generic IComparer.Compare erbt und einen Standardvergleich für einen bestimmten Typ T, a PropertyDescriptor
und eine Richtung implementiert. Diese Klasse erstellt dynamisch einen Comparer
von T, bei dem T der PropertyType
des PropertyDescriptor
ist. Anschließend wird der Standard-Comparer aus der statischen generischen Generika Comparer
abgerufen. Eine Standardinstanz wird durch Reflektion erzeugt.
Generic SortableBindingList
ist auch die Basisklasse für DataBindingList
. Eine generische SortableBindingList
bietet zwei virtuelle Methoden zum Unterbrechen oder Fortsetzen der Verfolgung des Hinzufügens/Entfernens von Elementen. Diese beiden Methoden können für Basisfeatures wie das Sortieren verwendet werden, werden aber tatsächlich von Oberklassen wie generischen DataBindingList
implementiert.
Generische DataBindingList
Diese Klasse erbt von dem generischen SortableBindingLIst
. Die generische DataBindingList
behält einen Verweis auf die zugrunde liegende generische Table
der generischen IQueryable
bei, die für das erste Füllen der Auflistung verwendet wurde. Die generische DatabindingList
fügt die Verfolgung für das Hinzufügen/Entfernen von Elementen hinzu, indem Sie InsertItem
() und RemoveItem
() überschreiben. Außerdem wird die abstrakte Funktion zur Unterbrechung/Wiederaufnahme der Verfolgung implementiert, um eine bedingte Verfolgung zu ermöglichen. Mit dieser Funktion nutzt die generische DataBindingList
die Vorteile der polymorphen Verwendung der Verfolgungsfunktion für übergeordnete Klassen.
Binden an EntitySets
Die Bindung an EntitySet
ist ein Sonderfall, da EntitySet
bereits eine Sammlung ist, die IBindingList implementiert. LINQ to SQL fügt Sortier- und Abbruchunterstützung hinzuICancelAddNew. Eine EntitySet
Klasse verwendet eine interne Liste zum Speichern von Entitäten. Diese Liste ist eine Auflistung auf niedriger Ebene basierend auf einem generischen Array, der generischen ItemList
Klasse.
Hinzufügen eines Sortierfeatures
Arrays bieten eine Sortiermethode (Array.Sort()
), die Sie mit einer Comparer
von T verwenden können. LINQ to SQL verwendet die weiter oben in diesem Thema beschriebene generische SortableBindingList.PropertyComparer
Klasse, um dies Comparer
für die Eigenschaft und die Richtung abzurufen, nach der sortiert werden soll. Eine ApplySort
-Methode wird der generischen ItemList
hinzugefügt, um diese Funktion aufzurufen.
Auf der EntitySet
Seite müssen Sie jetzt die Sortierunterstützung deklarieren:
SupportsSorting gibt
true
zurück.ApplySort ruft
entities.ApplySort()
und dannOnListChanged()
.SortDirection und SortProperty Eigenschaften machen die aktuelle Sortierdefinition verfügbar, die in lokalen Mitgliedern gespeichert ist.
Wenn Sie eine System.Windows.Forms.BindingSource verwenden und ein EntitySet<TEntity> an System.Windows.Forms.BindingSource.DataSource binden, müssen Sie EntitySet<TEntity>.GetNewBindingList aufrufen, um BindingSource.List zu aktualisieren.
Wenn Sie eine „System.Windows.Forms.BindingSource“ verwenden, die „BindingSource.DataMember“-Eigenschaft festgelegt haben und für die „BindingSource.DataSource“ eine Klasse mit einer Eigenschaft festgelegt haben, die im „BindingSource.DataMember“ angegeben ist, der die „EntitySet<TEntity>“ verfügbar macht, müssen Sie „EntitySet<TEntity>.GetNewBindingList“ nicht aufrufen, um die „BindingSource.List“ zu aktualisieren. Dabei geht jedoch die Sortierfunktion verloren.
Zwischenspeicherung
LINQ to SQL-Abfragen implementieren GetList. Wenn die Windows Forms BindingSource-Klasse diese Schnittstelle erfüllt, ruft sie GetList() dreimal für eine einzelne Verbindung auf. Um diese Situation zu umgehen, implementiert LINQ to SQL einen Cache pro Instanz, um sie zu speichern und immer dieselbe generierte Auflistung zurückzugeben.
Abbruch
IBindingList definiert eine AddNew Methode, die von Steuerelementen zum Erstellen eines neuen Elements aus einer gebundenen Auflistung verwendet wird. Das DataGridView
Steuerelement zeigt dieses Feature sehr gut an, wenn die letzte sichtbare Zeile einen Stern in der Kopfzeile enthält. Der Stern zeigt Ihnen, dass Sie ein neues Element hinzufügen können.
Zusätzlich zu dieser Funktion kann eine Sammlung auch ICancelAddNew implementieren. Dieses Feature ermöglicht es den Steuerelementen, abzubrechen oder zu überprüfen, ob das neue bearbeitete Element überprüft wurde oder nicht.
ICancelAddNew wird in allen LINQ to SQL-datengebundenen Sammlungen (generic SortableBindingList
und generic EntitySet
) implementiert. In beiden Implementierungen funktioniert der Code wie folgt:
Ermöglicht das Einfügen und Entfernen von Elementen aus der Auflistung.
Verfolgt keine Änderungen, solange die Benutzeroberfläche keinen Commit für die Bearbeitung ausführt.
Änderungen werden nicht nachverfolgt, solange die Edition abgebrochen wird (CancelNew).
Ermöglicht die Verfolgung, wenn die Bearbeitung aktiviert wurde (EndNew).
Sorgt für das normale Verhalten der Auflistung, wenn das neue Element nicht aus AddNew stammt.
Problembehandlung
In diesem Abschnitt werden mehrere Elemente aufgerufen, die ihnen bei der Problembehandlung bei LINQ to SQL-Datenbindungsanwendungen helfen können.
Sie müssen Eigenschaften verwenden; Die Verwendung von Feldern reicht nicht aus. Windows Forms erfordert diese Verwendung.
Standardmäßig werden die Datenbanktypen
image
,varbinary
undtimestamp
einem Byte-Array zugeordnet. DaToString()
in diesem Szenario nicht unterstützt wird, können diese Objekte nicht angezeigt werden.Ein einem Primärschlüssel zugeordnetes Klassenmitglied hat einen Setter, aber LINQ to SQL unterstützt keine Objektidentitätsänderung. Daher kann der primär/eindeutige Schlüssel, der in der Zuordnung verwendet wird, nicht in der Datenbank aktualisiert werden. Eine Änderung im Raster verursacht eine Ausnahme beim Aufrufen von SubmitChanges.
Wenn eine Entität in zwei separaten Rastern gebunden ist (z. B. ein Master-Raster und ein weiteres Detailraster), wird ein
Delete
im Masterraster nicht an das Detailraster weitergegeben.