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 IEnumerable
typu . 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 PropertyDescriptor
a 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í:
SupportsSorting vrátí
true
.ApplySort a
entities.ApplySort()
pakOnListChanged()
.SortDirection a SortProperty vlastnosti zveřejňují aktuální definici řazení, která je uložena v místních členech.
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
image
varbinary
typy databází atimestamp
typy databází mapují na bajtové pole. Vzhledem k tomuToString()
, ž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.