Adatkapcsolás

A LINQ–SQL támogatja a közös vezérlőkhöz, például a rácsvezérlőkhöz való kötést. A LINQ to SQL határozza meg az alapvető mintákat az adatrácshoz való kötéshez és a mester-részlet kötés kezeléséhez, mind a megjelenítés, mind a frissítés tekintetében.

Mögöttes elv

A LINQ-ről SQL-re lefordítja a LINQ-lekérdezéseket az SQL-nek az adatbázison való végrehajtáshoz. Az eredmények erősen be vannak gépelve IEnumerable. Mivel ezek az objektumok szokásos közös nyelvi futtatókörnyezeti (CLR-) objektumok, az eredmények megjelenítéséhez szokásos objektumadat-kötés használható. A módosítási műveletek (beszúrások, frissítések és törlések) azonban további lépéseket igényelnek.

Művelet

A Windows Forms-vezérlőkhöz való implicit kötés megvalósítása az IListSource implementálásával történik. Az adatforrások generikus Table<TEntity> (Table<T> C# vagy Table(Of T) Visual Basic nyelven) és a generikus DataQuery frissítve lettek az IListSource implementálására. A felhasználói felület (UI) adatkötési motorjai (Windows Forms és Windows Presentation Foundation) egyaránt tesztelik, hogy az adatforrás implementálva IListSourcevan-e. Ezért a lekérdezés közvetlen befolyásolásának írása egy vezérlő adatforrására implicit módon meghívja a LINQ-t az SQL-gyűjtemény generálására, ahogyan az alábbi példában is látható:

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

Ugyanez történik a Windows Presentation Foundation esetében is:

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

A gyűjteménygenerációkat az általános Table<TEntity> és az általános DataQuery hajtják végre GetList-ben.

IListSource-implementáció

A LINQ to SQL IListSource megvalósítása két helyen történik:

  • Az adatforrás a Table<TEntity>: a LINQ to SQL átnézi a táblát, hogy megtöltsön egy DataBindingList gyűjteményt, amely a táblára hivatkozást tart meg.

  • Az adatforrás egy IQueryable<T>. Két forgatókönyv létezik:

    • Ha a LINQ to SQL megtalálja a Table<TEntity>-t a IQueryable<T>-ből, a forrás lehetővé teszi a szerkesztését, és a helyzet ugyanaz, mint az első felsorolási pontban.

    • Ha a LINQ az SQL-nek nem találja az alapul szolgálót Table<TEntity>, a forrás nem engedélyezi a kiadást (például groupby). A LINQ to SQL feldolgozza a lekérdezést egy általános SortableBindingList kitöltéséhez, amely egyszerű BindingList<T>, és amely T entitások rendezési funkcióját valósítja meg egy adott tulajdonságra.

Specializált gyűjtemények

A dokumentum BindingList<T> korábbi részében ismertetett számos funkció esetében különböző osztályokra specializálódott. Ezek az osztályok általánosak SortableBindingList és általánosak DataBindingList. Mindkettő belsőként van deklarálva.

Generic SorbarendezhetőKötésiLista

Ez az osztály örökli a BindingList<T> tulajdonságait, és jelenleg a BindingList<T> rendezhető verziója. A rendezés memóriabeli megoldás, és soha nem lép kapcsolatba magával az adatbázissal. BindingList<T> implementálja IBindingList, de nem támogatja a rendezést alapértelmezés szerint. Azonban BindingList<T> az IBindingList virtuális mag metódusokkal implementálja. Ezeket a metódusokat egyszerűen felülbírálhatja. Az általános SortableBindingList felülbírálja a SupportsSortingCore, SortPropertyCore, SortDirectionCore és ApplySortCore. ApplySortCore-t a ApplySort hívja meg, és rendezi az adott tulajdonsághoz tartozó T-elemek listáját.

Kivétel akkor keletkezik, ha a tulajdonság nem T tulajdona.

A rendezés megvalósítása érdekében a LINQ to SQL létrehoz egy általános SortableBindingList.PropertyComparer osztályt, amely az általános IComparer.Compare-ből örököl, és implementál egy alapértelmezett komparátort egy adott T típushoz, egy PropertyDescriptor-höz és egy irányhoz. Ez az osztály dinamikusan létrehoz egy T típusú Comparer-t, ahol T a PropertyType a PropertyDescriptor. Ezután az alapértelmezett összehasonlítót a statikus generikusból kérdezhetjük le Comparer. A rendszer az alapértelmezett példányt visszatükrözéssel szerzi be.

A Generic SortableBindingList az alap osztály a DataBindingList számára is. Az Generic SortableBindingList két virtuális módszert kínál az elemek nyomon követésének felfüggesztésére vagy folytatására. Ez a két módszer használható olyan alapfunkciókhoz, mint a rendezés, de valójában például az általános DataBindingList-hoz hasonló felsőbb osztályok implementálják.

Általános DataBindingLista

Ez az osztály az SortableBindingLIst általánostól öröklődik. A Generic DataBindingList hivatkozik a gyűjtemény kezdeti kitöltéséhez használt generikus Table mögöttes generikusára IQueryable. Az Generic DatabindingList az elem hozzáadásának és eltávolításának nyomon követését biztosítja a gyűjteményben a InsertItem() és a RemoveItem() metódusok felülírásával. Emellett implementálja az absztrakt felfüggesztési/folytatáskövetési funkciót is, hogy a nyomon követés feltételes legyen. Ez a funkció kihasználja a szülőosztályok nyomkövetési funkciójának polimorfikus használatát általánosan.

Kötés objektumhalmazokhoz

EntitySet kötés egy speciális eset, mert EntitySet már egy olyan kollekció, amely implementálja a IBindingList-t. A LINQ az SQL-hez rendezési és megszakítási (ICancelAddNew) támogatást biztosít. Az EntitySet osztály egy belső listát használ az entitások tárolására. Ez a lista egy alacsony szintű gyűjtemény, amely egy általános tömbön, az általános ItemList osztályon alapul.

Rendezési funkció hozzáadása

A tömbök rendezési módszert kínálnak (Array.Sort()), amelyet egy T típusú LINQ to SQL Comparer-vel lehet használni. A LINQ to SQL a jelen témakörben korábban ismertetett általános SortableBindingList.PropertyComparer osztályt használja a tulajdonság és a rendezés irányának Comparer beolvasásához. A ApplySort metódust adunk hozzá az általános ItemList-hoz a funkció meghívásához.

Ezen az EntitySet oldalon most a rendezési támogatást kell deklarálnia:

Ha System.Windows.Forms.BindingSource-t használ, és egy EntitySet<TEntity-t> köt a System.Windows.Forms.BindingSource.DataSource-hoz, meg kell hívnia az EntitySet<TEntityet>. GetNewBindingList a BindingSource.List frissítéséhez.

Ha System.Windows.Forms.BindingSource-t használ, és a BindingSource.DataMember tulajdonságot állítja be, és a BindingSource.DataSource-t olyan osztályra állítja, amelynek a BindingSource.DataMember nevű tulajdonsága az EntitySet<TEntity> függvényt teszi elérhetővé, nem kell meghívnia az EntitySet<TEntityet>. GetNewBindingList a BindingSource.List frissítéséhez, de elveszíti a rendezési képességet.

Gyorsítótár

LINQ–SQL-lekérdezések implementálása GetList. Amikor a Windows Forms BindingSource osztály megfelel ennek a felületnek, három alkalommal hívja meg a GetList() függvényt egyetlen kapcsolatra. A probléma megoldásához a LINQ–SQL példányonként egy gyorsítótárat implementál, és mindig ugyanazt a létrehozott gyűjteményt adja vissza.

Lemondás

IBindingList egy metódust AddNew határoz meg, amelyet a vezérlők használnak új elem létrehozásához egy kötött gyűjteményből. A DataGridView vezérlő nagyon jól mutatja ezt a funkciót, ha az utolsó látható sor egy csillagot tartalmaz a fejlécében. A csillag jelzi, hogy hozzáadhat egy új elemet.

A funkció mellett egy gyűjtemény is képes implementálni ICancelAddNew. Ez a funkció lehetővé teszi a vezérlők számára, hogy visszavonják a műveletet, vagy érvényesítsék, hogy az új szerkesztett elemet megerősítették-e vagy sem.

ICancelAddNew minden LINQ to SQL adatkapcsolat-gyűjteményben végrehajtva van (generikus SortableBindingList és generikus EntitySet). Mindkét implementációban a kód a következőképpen teljesít:

  • Lehetővé teszi az elemek beszúrását és eltávolítását a gyűjteményből.

  • Nem követi nyomon a módosításokat, amíg a felhasználói felület nem véglegesíti a kiadást.

  • Mindaddig nem követi nyomon a módosításokat, amíg a kiadást megszakítja (CancelNew).

  • Lehetővé teszi a kiadás véglegesítése (EndNew) nyomon követését.

  • Lehetővé teszi, hogy a gyűjtemény megfelelően viselkedjen, ha az új elem nem a AddNew-ból származik.

Hibaelhárítás

Ez a szakasz számos olyan elemet hív fel, amelyek segíthetnek a LINQ és az SQL-adatkötési alkalmazások hibaelhárításában.

  • Tulajdonságokat kell használnia; a csak mezők használata nem elegendő. A Windows Forms megköveteli ezt a használatot.

  • Alapértelmezés szerint a image, varbinary és timestamp adatbázistípusok bájttömbre vannak leképezve. Mivel ToString() ebben a forgatókönyvben nem támogatott, ezek az objektumok nem jeleníthetők meg.

  • Az elsődleges kulcsra leképezett osztálytag rendelkezik egy beállítóval, de az SQL-hez tartozó LINQ nem támogatja az objektum identitásának módosítását. Ezért a leképezésben használt elsődleges/egyedi kulcs nem frissíthető az adatbázisban. A rács változása okoz egy kivételt, amikor a SubmitChanges hívás történik.

  • Ha egy entitás két külön rácsba van kötve (például egy fő és egy másik részlet), a rendszer nem propagálja a főrács egy Delete elemét a részletrácsra.

Lásd még