Opět se vrátím k úvodnímu přehledovému článku o všech variantách LINQu, kde jsem napsal:

"LINQ over DataSet - zjednodušeně řečeno se jedná o sadu wrapperů a extenzí nad objekty datasetu (tabulka, řádek apod.), které tyto objekty zpřístupňují jako IEnumerable<T> kolekce, se kterými lze manipulovat pomocí LINQ to IEnumerable<T>. Nacházejí se v knihovně System.Data.DataSetExtensions. Více někdy příště."

Oproti ostatním LINQům je ten datasetový poměrně minimalistický. Původní objekt DataTable totiž vznikla ještě před příchodem generických enumerátorů a LINQ s ním tudíž neuměl zacházet. Přidaná funkce se v podstatě omezuje na konverzi z DataTable na IEnumerable<DataRow> a zpět. Interně jsou navíc přetíženy některé extenzní metody (Where,OrderBy apod.), aby využívali specifik DataSetu, např. hledání podle indexovaného primárního klíče bez nutnosti projít celou tabulku apod. Ve Visual Studiu 2008 byl zároveň přepracován generátor typových datasetů tak, že tabulky jsou odvozeny od nového typu TypedTableBase<T> (odvozeného od DataTable), takže pro typové datasety můžete začít využívat LINQ bez jakéhokoliv přemýšlení. Naopak pro netypové datasety je to poněkud otravné.

Podrobnější informace jsou dost rozptýlené, na oficiální LINQ stránce jsou dva odkazy na beznadějně zastaralý text (ani je nečtěte).

Následující příklad používá typový dataset KatalogProduktu skládající se z tabulek Product a ProductCategory z databáze AdventureWorksLT ("lite").

            KatalogProduktu katalogT = new KatalogProduktu();

            new KatalogProduktuTableAdapters.ProductCategoryTableAdapter().Fill(katalogT.ProductCategory);

            new KatalogProduktuTableAdapters.ProductTableAdapter().Fill(katalogT.Product);

 

            DataSet katalogNT = new DataSet();

            katalogNT.Tables.Add(katalogT.ProductCategory.Copy());

            katalogNT.Tables.Add(katalogT.Product.Copy());

            katalogNT.Relations.Add("CategoryToProducts", katalogNT.Tables["ProductCategory"].Columns["ProductCategoryID"], katalogNT.Tables["Product"].Columns["ProductCategoryID"]);

 

            // Extenze dovoluji prevest DataTable do formy, kde lze pouzit LINQ diky IEnumerable

            var draheProduktyT = from p in katalogT.Product where p.ListPrice > 3000 orderby p.Name select p;

            // Jde to i pro netypovy dataset, ale je to pekna otrava

            var produktyNT = katalogNT.Tables["Product"].AsEnumerable();

            var draheProduktyNT = from p in produktyNT where p.Field<decimal>("ListPrice") > 3000 orderby p.Field<string>("Name") select p;

            // Lze samozrejme prochazet i relace mezi tabulkami - bud pomoci standardnich metod nebo jde udelat join (neexistuje-li relace)

            var kolaT = from c in katalogT.ProductCategory where c.Name.Contains("Bikes")

                        from p in c.GetProductRows() select new {Product = p.Name, Category = c.Name};

            // a totez opet netypove

            var kategorieNT = katalogNT.Tables["ProductCategory"].AsEnumerable();

            var kolaNT = from c in kategorieNT where c.Field<string>("Name").Contains("Bikes")

                        from p in c.GetChildRows("CategoryToProducts") select new {Product = p.Field<string>("Name"), Category = c.Field<string>("Name")};

           

            // Naopak libovolne IEnumerable<DataRow> lze prevest na DataTable (novou nebo plnit existujici)

            DataSet katalogNT2 = new DataSet();

            DataTable tabulkaDraheNT = draheProduktyNT.CopyToDataTable();

            tabulkaDraheNT.TableName = "DraheProdukty";

            katalogNT2.Tables.Add(tabulkaDraheNT);

            KatalogProduktu katalogT2 = new KatalogProduktu();

            draheProduktyT.CopyToDataTable(katalogT2.Product, LoadOption.OverwriteChanges);