Ahhoz, hogy egy adatforrásból adatot nyerjünk ki, az adatforrás saját API-ját kell használnunk. Például egy SQL szervernek az ADO.NET segítségével küldünk egy SQL queryt, és így kapjuk meg a kívánt adatot; XML-ből viszont XPath vagy valamilyen XML DOM API segítségével nyerhetünk ki adatot. Mivel minden adatforrás használatához más API szükséges, ezért ezek megtanulása sok időt és energiát igényel. A LINQ ennek a megoldására lett létrehozva.
A LINQ-t három kategóriába lehet osztani:
- LINQ: Language Integrated Query for in memory objects
- DINQ: Language Integrated Query for databases
- XLINQ: Language Integrated Query for XML
A Microsoft úgy tervezte a LINQ-t, hogy minden olyan adattal tudjon dolgozni, ami implementálta az IEnumerable interfészt.

A következő példában egy string tömbből válasszuk ki a 4 karakter hosszú stringeket:
string[] gyumolcsok = { "alma", "körte", "eper", "kivi", "barack" };
IEnumerable<string> query = from n in gyumolcsok
where n.Length == 4
select n;
foreach (string gyumolcs in query) Console.WriteLine(gyumolcs);
LINQ használata objektumokon
Bármikor, amikor tömbökkel vagy listákkal dolgozol használhatsz LINQ kifejezéseket. Az unalmas foreach ciklusokat az if-ekkel bennük, le tudod cserélni egy szépen olvasható LINQ kifejezésre, így szebb, olvashatóbb és rövidebb kódod lesz.
Tegyük fel, hogy meg szeretnéd keresni az összes svchost.exe futó alkalmazást, majd memóriahasználatuk szerint sorrendbe rendezni. Ezt eddig így csináltad meg .Net 2.0-ban:
List<Process> svchostLista = new List<Process>();
foreach (Process p in Process.GetProcesses())
{
if(p.ProcessName == "svchost")
{
svchostLista.Add(p);
}
}
svchostLista.Sort(delegate(Process p1, Process p2)
{
return p2.WorkingSet64.CompareTo(p1.WorkingSet64);
});
Le lehet egyszerűsíteni lambda kifejezésekkel:
List<Process> svchostLista = new List<Process>(
Process.GetProcesses().ToList().FindAll(p => String.Equals(p.ProcessName, "svchost"))
);
svchostLista.Sort((p1, p2) => p2.WorkingSet64.CompareTo(p1.WorkingSet64));
Habár a munkát elvégzi, az utánad következő fejlesztőnek kicsit fejfájás lesz e kódot módosítani. Most viszont itt van ugyan ez, LINQ kifejezésekkel:
IEnumerable<Process> svchostLista = from p in Process.GetProcesses()
where p.ProcessName == "svchost"
orderby p.WorkingSet64 descending
select p;
Könnyen érthető és módosítható.
LINQ használata XML fájlokon
Sok XML API létezik, a LINQ viszont különleges, mivel nem csak XML-t ismer, de az XML-en belül használhatsz XML DOM vagy XPath-et is.
A legelső string tömbös példa XML megfelelője:
XElement gyumolcsok = XElement.Parse(
@"<gyumolcsok>
<gyumolcs>alma</gyumolcs>
<gyumolcs>körte</gyumolcs>
<gyumolcs>eper</gyumolcs>
<gyumolcs>kivi</gyumolcs>
<gyumolcs>barack</gyumolcs>
</gyumolcsok›"
);
IEnumerable<string> query = from n in gyumolcsok.Elements("gyumolcs")
where n.Value.Length == 4
select n.Value;
foreach (string gyumolcs in query) Console.WriteLine(gyumolcs);
Ha csak annyit szeretnénk megtudni, hogy az XML fájlban tárolt gyümölcsök közül hány kezdődik k betűvel, akkor a következő kód:
int hanyKBetu = (from i in gyumolcsok.Elements("gyumolcs") where i.Value.StartsWith("k") select i).Count();
Ebben az esetben a következő megoldás viszont rövidebb:
int hanyKBetu = gyumolcsok.Elements("gyumolcs").Where(i => i.Value.StartsWith("k")).Count();
A .Net 3.5-ben be lett vezetve az XElement, amely megengedi az XML fájlok funkcionális készítését:
XElement gyumolcsok =
new XElement("gyumolcsok",
new XElement("gyumolcs", "alma"),
new XElement("gyumolcs", "körte"),
new XElement("gyumolcs", "eper"),
new XElement("gyumolcs", "kivi"),
new XElement("gyumolcs", "barack")
);
Ha a gyumolcsok-re meghívjuk a ToString() függvényt, akkor megkapjuk a fentebb is látható XML fájlt.
LINQ használata SQL adatbázisokon
Ahhoz, hogy LINQ kifejezéseket használhassunk SQL adatbázisokon az első lépés az, hogy elkészítjük a táblánknak megfelelő osztályt.
A Northwind adatbázis Customer táblájának megfelelő osztály így néz ki:
[Table(Name = "dbo.Customers")]
public partial class Customer
{
[Column(IsPrimaryKey = true)]
public string CustomerID
{
get
{
return this._CustomerID;
}
set
{
if ((this._CustomerID != value))
{
this._CustomerID = value;
}
}
}
private string _CustomerID;
[Column]
public string CompanyName
{
get
{
return this._CompanyName;
}
set
{
if ((this._CompanyName != value))
{
this._CompanyName = value;
}
}
}
// és így tovább...
}
Két megoldás van arra, hogy egy osztályt egy táblához kössünk. Az egyik a fenti kód, ahol külön megírjuk a Table és Column részeket, míg a második megoldás a külső XML fájlok használata. Mindkét megoldáshoz vannak automatikus generátorok, mint például az sqlmetal.exe.
A DataContext osztály lefordítja a LINQ kifejezéseket SQL kifejezésekre, majd lefuttatja az adatbázison.
Ha a Northwind adatbázisból le szeretnénk tölteni a francia ügyfeleket, akkor a következő LINQ kifejezést futtatjuk le:
IEnumerable<Customer> ugyfelek = from c in context.Customers
where c.Country == "France"
orderby c.CustomerID ascending
select c;
Ez le lesz fordítva a következő SQL kifejezéssé:
SELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], [t0].[ContactTitle], [t0].[Address],
[t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[Country], [t0].[Phone], [t0].[Fax]
FROM [dbo].[Customers] AS [t0]
WHERE [t0].[Country] = @p0
ORDER BY [t0].[CustomerID]
A LINQ to SQL nagyon komplex kifejezéseket is képes megérteni és lefordítani, például amelyek két táblát join-olnak. Vannak esetek, ahol már túl komplex lesz egy query, és a LINQ to SQL már nem lesz képes megérteni; ilyenkor az Entity Framework-öt kell használni.
lab.rolisoft.net