Powiązanie danych
LinQ to SQL obsługuje powiązanie z typowymi kontrolkami, takimi jak kontrolki siatki. W szczególności LINQ to SQL definiuje podstawowe wzorce powiązania z siatką danych i obsługą powiązania szczegółów wzorca, zarówno w odniesieniu do wyświetlania, jak i aktualizowania.
Podstawowa zasada
LINQ to SQL tłumaczy zapytania LINQ na język SQL na potrzeby wykonywania w bazie danych. Wyniki są silnie typizowane IEnumerable
. Ponieważ te obiekty są zwykłymi obiektami środowiska uruchomieniowego języka wspólnego (CLR), do wyświetlania wyników można użyć zwykłego powiązania danych obiektu. Z drugiej strony operacje zmiany (operacje wstawiania, aktualizacji i usuwania) wymagają dodatkowych kroków.
Operacja
Niejawnie powiązanie z kontrolkami windows Forms odbywa się przez zaimplementowanie elementu IListSource. Źródła danych ogólne Table<TEntity> (Table<T>
w języku C# lub Table(Of T)
Visual Basic) i ogólne DataQuery
zostały zaktualizowane w celu zaimplementowania elementu IListSource. Aparaty powiązań danych interfejsu użytkownika (Windows Forms i Windows Presentation Foundation) testują, czy ich źródło danych implementuje IListSourceelement . W związku z tym pisanie bezpośredniego wpływu zapytania do źródła danych kontrolki niejawnie wywołuje generowanie kolekcji LINQ to SQL, jak w poniższym przykładzie:
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
Dzieje się tak samo w przypadku programu 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
Generacje kolekcji są implementowane przez typy ogólne Table<TEntity> i ogólne DataQuery
w systemie GetList.
Implementacja IListSource
LINQ to SQL implementuje IListSource w dwóch lokalizacjach:
Źródło danych to Table<TEntity>: LINQ to SQL przegląda tabelę
DataBindingList
w celu wypełnienia kolekcji, która przechowuje odwołanie do tabeli.Źródło danych to IQueryable<T>. Istnieją dwa scenariusze:
Jeśli funkcja LINQ to SQL znajdzie źródło Table<TEntity> z IQueryable<T>elementu , źródło zezwala na edycję, a sytuacja jest taka sama jak w pierwszym punkcie punktora.
Jeśli linQ to SQL nie może odnaleźć bazowego Table<TEntity>elementu , źródło nie zezwala na edycję (na przykład
groupby
). LINQ to SQL przegląda zapytanie, aby wypełnić ogólnySortableBindingList
element , który jest prosty BindingList<T> , który implementuje funkcję sortowania dla jednostek T dla danej właściwości.
Specjalne kolekcje
W przypadku wielu funkcji opisanych wcześniej w tym dokumencie BindingList<T> została wyspecjalizowana w niektórych różnych klasach. Te klasy są ogólne SortableBindingList
i ogólne DataBindingList
. Oba są deklarowane jako wewnętrzne.
Ogólna lista sortableBindingList
Ta klasa dziedziczy z BindingList<T>klasy i jest sortowalnym wersją klasy BindingList<T>. Sortowanie jest rozwiązaniem w pamięci i nigdy nie kontaktuje się z samą bazą danych. BindingList<T> implementuje IBindingList , ale nie obsługuje sortowania domyślnie. BindingList<T> Jednak implementuje za IBindingList pomocą metod rdzeni wirtualnych. Te metody można łatwo zastąpić. Przesłonięcia SupportsSortingCoreogólneSortableBindingList
, , SortPropertyCore, SortDirectionCorei ApplySortCore. ApplySortCore
element jest wywoływany przez ApplySort i sortuje listę elementów T dla danej właściwości.
Wyjątek jest zgłaszany, jeśli właściwość nie należy do T.
Aby osiągnąć sortowanie, LINQ to SQL tworzy klasę ogólną, która dziedziczy po klasie SortableBindingList.PropertyComparer
ogólnej IComparer.Compare i implementuje domyślny moduł porównujący dla danego typu T, a PropertyDescriptor
i kierunku. Ta klasa dynamicznie tworzy klasę Comparer
T, gdzie T jest wartością PropertyType
PropertyDescriptor
. Następnie domyślny moduł porównujący jest pobierany ze statycznego ogólnego elementu Comparer
. Wystąpienie domyślne jest uzyskiwane przy użyciu odbicia.
Generic SortableBindingList
jest również klasą bazową dla klasy DataBindingList
. Generic SortableBindingList
oferuje dwie metody wirtualne do zawieszania lub wznawiania elementów dodawania/usuwania śledzenia. Te dwie metody mogą służyć do obsługi podstawowych funkcji, takich jak sortowanie, ale naprawdę będą implementowane przez wyższe klasy, takie jak ogólne DataBindingList
.
Generic DataBindingList
Ta klasa dziedziczy z klasy ogólnej SortableBindingLIst
. Ogólny DataBindingList
przechowuje odwołanie do podstawowego rodzaju Table
ogólnego IQueryable
używanego do początkowego wypełniania kolekcji. Ogólne DatabindingList
dodaje śledzenie dodawania/usuwania elementu do kolekcji przez zastąpienie InsertItem
() i RemoveItem
(). Implementuje również abstrakcyjną funkcję śledzenia wstrzymania/wznawiania w celu warunkowego śledzenia. Ta funkcja sprawia, że ogólne DataBindingList
wykorzystanie wszystkich funkcji polimorficznych funkcji śledzenia klas nadrzędnych.
Wiązanie z zestawami EntitySet
Powiązanie z EntitySet
elementem jest specjalnym przypadkiem, ponieważ EntitySet
jest to już kolekcja, która implementuje IBindingListelement . LinQ to SQL dodaje obsługę sortowania i anulowania (ICancelAddNew). Klasa EntitySet
używa wewnętrznej listy do przechowywania jednostek. Ta lista jest kolekcją niskiego poziomu opartą na tablicy ogólnej, klasie ogólnej ItemList
.
Dodawanie funkcji sortowania
Tablice oferują metodę sortowania (Array.Sort()
), której można użyć z funkcją Comparer
T. LINQ to SQL używa klasy ogólnej SortableBindingList.PropertyComparer
opisanej wcześniej w tym temacie, aby uzyskać tę Comparer
metodę dla właściwości i kierunku sortowania. Metoda ApplySort
jest dodawana do metody ogólnej ItemList
w celu wywołania tej funkcji.
EntitySet
Po stronie musisz teraz zadeklarować obsługę sortowania:
SupportsSorting zwraca wartość
true
.ApplySort wywołuje
entities.ApplySort()
metodę , a następnieOnListChanged()
.SortDirection i SortProperty właściwości uwidacznia bieżącą definicję sortowania, która jest przechowywana w lokalnych elementach członkowskich.
Jeśli używasz elementu System.Windows.Forms.BindingSource i powiąż element EntitySet TEntity> z elementem System.Windows.Forms.BindingSource.DataSource, musisz wywołać metodę EntitySet<<TEntity>. GetNewBindingList, aby zaktualizować plik BindingSource.List.
Jeśli używasz właściwości System.Windows.Forms.BindingSource i ustawisz właściwość BindingSource.DataMember i ustaw właściwość BindingSource.DataSource na klasę, która ma właściwość o nazwie BindingSource.DataMember, która uwidacznia element EntitySet TEntity, nie musisz wywoływać klasy EntitySet<<TEntity>>. PobierzNewBindingList, aby zaktualizować plik BindingSource.List, ale utracisz możliwość sortowania.
Buforowanie
Zapytania LINQ to SQL implementują element GetList. Gdy klasa BindingSource formularzy systemu Windows spełnia ten interfejs, wywołuje metodę GetList() trzykrotnie dla pojedynczego połączenia. Aby obejść tę sytuację, linQ to SQL implementuje pamięć podręczną na wystąpienie do przechowywania i zawsze zwraca tę samą wygenerowaną kolekcję.
Anulowanie
IBindingList definiuje metodę używaną AddNew przez kontrolki do tworzenia nowego elementu na podstawie powiązanej kolekcji. Kontrolka DataGridView
pokazuje tę funkcję bardzo dobrze, gdy ostatni widoczny wiersz zawiera gwiazdkę w nagłówku. Gwiazdka pokazuje, że możesz dodać nowy element.
Oprócz tej funkcji kolekcja może również implementować ICancelAddNewelement . Ta funkcja umożliwia kontrolkom anulowanie lub sprawdzenie, czy nowy edytowany element został zweryfikowany, czy nie.
ICancelAddNew jest implementowany we wszystkich kolekcjach danych LINQ to SQL (ogólnych i ogólnych SortableBindingList
EntitySet
). W obu implementacjach kod działa w następujący sposób:
Umożliwia wstawianie elementów, a następnie usuwanie ich z kolekcji.
Nie śledzi zmian, o ile interfejs użytkownika nie zatwierdza wersji.
Nie śledzi zmian, o ile wersja zostanie anulowana (CancelNew).
Umożliwia śledzenie, gdy wersja jest zatwierdzona (EndNew).
Umożliwia, aby kolekcja zachowywała się normalnie, jeśli nowy element nie pochodzi z elementu AddNew.
Rozwiązywanie problemów
W tej sekcji przedstawiono kilka elementów, które mogą pomóc w rozwiązywaniu problemów z aplikacjami powiązania danych LINQ to SQL.
Musisz użyć właściwości; używanie tylko pól nie jest wystarczające. Formularze systemu Windows wymagają tego użycia.
Domyślnie typy
image
baz danych ,varbinary
itimestamp
są mapowane na tablicę bajtów. PonieważToString()
nie jest obsługiwany w tym scenariuszu, nie można wyświetlić tych obiektów.Element członkowski klasy zamapowany na klucz podstawowy ma element setter, ale LINQ to SQL nie obsługuje zmiany tożsamości obiektu. W związku z tym nie można zaktualizować klucza podstawowego/unikatowego używanego w mapowaniu w bazie danych. Zmiana siatki powoduje wyjątek podczas wywoływania metody SubmitChanges.
Jeśli jednostka jest powiązana w dwóch oddzielnych siatkach (na przykład jeden wzorzec i drugi szczegół),
Delete
siatka główna nie jest propagowana do siatki szczegółów.