Sdílet prostřednictvím


Datová vazba

LINQ to SQL podporuje vazbu na běžné ovládací prvky, jako jsou například ovládací prvky mřížky. LinQ to SQL konkrétně definuje základní vzory pro vazbu k datové mřížce a zpracování vazby hlavních podrobností, a to jak s ohledem na zobrazení, tak aktualizaci.

Základní princip

LINQ to SQL překládá dotazy LINQ na SQL pro spouštění v databázi. Výsledky jsou silného IEnumerabletypu . Vzhledem k tomu, že tyto objekty jsou běžné objekty CLR (Common Language Runtime), lze k zobrazení výsledků použít běžnou datová vazbu objektu. Na druhou stranu operace změn (vložení, aktualizace a odstranění) vyžadují další kroky.

Operace

Implicitně vazby na model Windows Forms ovládací prvky se provádí implementací IListSource. Zdroje dat obecné Table<TEntity> (Table<T> v jazyce C# nebo Table(Of T) v jazyce Visual Basic) a obecné DataQuery byly aktualizovány tak, aby implementovaly IListSource. Moduly pro datové vazby uživatelského rozhraní (model Windows Forms a Windows Presentation Foundation) testují, zda jejich zdroj dat implementuje IListSource. Proto zápis přímého vlivu dotazu na zdroj dat ovládacího prvku implicitně volá linQ to SQL collection generation, jako v následujícím příkladu:

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

Totéž se děje se službou 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

Generace kolekcí jsou implementovány obecnými Table<TEntity> a obecnými DataQuery v GetList.

Implementace IListSource

LINQ to SQL implementuje IListSource ve dvou umístěních:

  • Zdrojem dat je Table<TEntity>: LINQ to SQL prochází tabulku a vyplní DataBindingList kolekci, která uchovává odkaz na tabulku.

  • Zdroj dat je .IQueryable<T> Existují dva scénáře:

    • Pokud LINQ to SQL najde podklad Table<TEntity> z jazyka IQueryable<T>, zdroj umožňuje edici a situace je stejná jako v prvním odrážkovém bodu.

    • Pokud LINQ to SQL nemůže najít podkladovou Table<TEntity>sadu , zdroj neumožňuje edici (například groupby). LINQ to SQL prochází dotaz tak, aby vyplnil obecný SortableBindingList, což je jednoduchá BindingList<T> implementace funkce řazení pro entity T pro danou vlastnost.

Specializované kolekce

Pro mnoho funkcí popsaných dříve v tomto dokumentu BindingList<T> se specializuje na některé různé třídy. Tyto třídy jsou obecné SortableBindingList a obecné DataBindingList. Obě jsou deklarovány jako interní.

Obecný seznam sortableBindingList

Tato třída dědí z BindingList<T>, a je seřazená verze BindingList<T>. Řazení je řešení v paměti a nikdy nes kontaktuje samotnou databázi. BindingList<T> implementuje IBindingList , ale nepodporuje řazení ve výchozím nastavení. BindingList<T> Implementuje se ale s virtuálními základními metodamiIBindingList. Tyto metody můžete snadno přepsat. Obecná SortableBindingList přepsání SupportsSortingCore, SortPropertyCore, SortDirectionCore, a ApplySortCore. ApplySortCore je volána podle ApplySort a seřadí seznam položek T pro danou vlastnost.

Výjimka je vyvolána, pokud vlastnost nepatří do T.

Aby bylo možné dosáhnout řazení, LINQ to SQL vytvoří obecnou SortableBindingList.PropertyComparer třídu, která dědí z obecných IComparer.Compare typů a implementuje výchozí porovnávač pro daný typ T, a PropertyDescriptora směr. Tato třída dynamicky vytváří Comparer T, kde T je t je PropertyType .PropertyDescriptor Pak se výchozí porovnávač načte ze statického obecného souboru Comparer. Výchozí instance se získá pomocí reflexe.

Obecný SortableBindingList je také základní třídou pro DataBindingList. Generic SortableBindingList nabízí dvě virtuální metody pro pozastavení nebo obnovení položek pro sledování přidávání nebo odebírání. Tyto dvě metody lze použít pro základní funkce, jako je řazení, ale budou skutečně implementovány vyššími třídami, jako jsou obecné DataBindingList.

Generic DataBindingList

Tato třída dědí z obecného SortableBindingLIst. Generic DataBindingList uchovává odkaz na podkladový obecný typ Table obecného IQueryable použitého k počátečnímu vyplnění kolekce. Generic DatabindingList přidá sledování pro přidání nebo odebrání položky do kolekce přepsáním InsertItem() a RemoveItem(). Implementuje také abstraktní funkci sledování pozastavení a obnovení, aby bylo sledování podmíněné. Tato funkce využívá DataBindingList obecně všechny polymorfní použití funkce sledování nadřazených tříd.

Vazba na entitySets

Vazba na EntitySet je zvláštní případ, protože EntitySet již je kolekce, která implementuje IBindingList. LINQ to SQL přidává podporu řazení a rušení (ICancelAddNew). Třída EntitySet používá k ukládání entit interní seznam. Tento seznam je kolekce nízké úrovně založená na obecném poli, obecné ItemList třídě.

Přidání funkce řazení

Pole nabízejí metodu řazení (Array.Sort()), kterou můžete použít s Comparer T. LINQ to SQL používá obecnou SortableBindingList.PropertyComparer třídu popsanou výše v tomto tématu k získání této Comparer vlastnosti a směru řazení. K ApplySort volání této funkce se přidá ItemList metoda.

EntitySet Na straně teď musíte deklarovat podporu řazení:

Pokud používáte System.Windows.Forms.BindingSource a vazbu EntitySet<TEntity> na System.Windows.Forms.BindingSource.DataSource, musíte volat EntitySet<TEntity>. GetNewBindingList pro aktualizaci BindingSource.List.

Pokud používáte System.Windows.Forms.BindingSource a nastavíte BindingSource.DataMember vlastnost a nastavíte BindingSource.DataSource na třídu, která má vlastnost pojmenovanou v BindingSource.DataMember, která zveřejňuje EntitySet TEntity>, nemusíte volat EntitySet<<TEntity>. GetNewBindingList k aktualizaci BindingSource.List, ale ztratíte možnost řazení.

Ukládání do mezipaměti

Implementují GetListse dotazy LINQ to SQL . Když model Windows Forms BindingSource třída splňuje toto rozhraní, volá GetList() třikrát pro jedno připojení. Pokud chcete tuto situaci obejít, LINQ to SQL implementuje mezipaměť pro každou instanci pro uložení a vždy vrátí stejnou vygenerovanou kolekci.

Zrušení

IBindingList definuje metodu AddNew , která se používá ovládacími prvky k vytvoření nové položky z vázané kolekce. Ovládací DataGridView prvek tuto funkci zobrazuje velmi dobře, když poslední viditelný řádek obsahuje hvězdičku v záhlaví. Hvězdička ukazuje, že můžete přidat novou položku.

Kromě této funkce může kolekce také implementovat ICancelAddNew. Tato funkce umožňuje ovládacím prvkům zrušit nebo ověřit, že byla nová upravená položka ověřena nebo ne.

ICancelAddNew se implementuje ve všech kolekcích dat LINQ to SQL (obecné SortableBindingList a obecné EntitySet). V obou implementacích kód provádí takto:

  • Umožňuje vložit a odebrat položky z kolekce.

  • Nesleduje změny, pokud uživatelské rozhraní neschová edici.

  • Nesleduje změny, pokud je edice zrušena (CancelNew).

  • Umožňuje sledování při potvrzení edice (EndNew).

  • Umožňuje kolekci chovat normálně, pokud nová položka nepochází z AddNew.

Řešení problému

Tato část popisuje několik položek, které vám můžou pomoct s řešením potíží s aplikacemi pro datové vazby LINQ to SQL.

  • Je nutné použít vlastnosti; použití pouze polí nestačí. model Windows Forms toto použití vyžadovat.

  • Ve výchozím nastavení se imagevarbinarytypy databází a timestamp typy databází mapují na bajtové pole. Vzhledem k tomu ToString() , že tento scénář není podporován, nelze tyto objekty zobrazit.

  • Člen třídy namapovaný na primární klíč má setter, ale LINQ to SQL nepodporuje změnu identity objektu. Proto primární nebo jedinečný klíč, který se používá při mapování, nelze v databázi aktualizovat. Změna v mřížce způsobí výjimku při volání SubmitChanges.

  • Pokud je entita svázaná ve dvou samostatných mřížkách (například jedna předloha a další podrobnosti), Delete nerozšíře se do mřížky podrobností mřížka v hlavní mřížce.

Viz také