Udostępnij za pośrednictwem


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ólny SortableBindingListelement , 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 PropertyDescriptori 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ępnie OnListChanged().

  • 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 imagebaz danych , varbinaryi timestamp 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.

Zobacz też