Linq (Language Integrated Query,語言集成查詢),是微軟公司提供的一項新技術,它可以將查詢功能引入到.NET 3.5 所支持的編程語言中,例如C#,Visual Basic.NET。查詢操做經過編程語言自身來表達,而再也不是以字符串的形式嵌入到應用程序中。node
Linq主要包含下面四個組件:web
Linq to Objets、Linq to Sql、Linq to DataSet和Linq to XML,它們分別用於查詢和處理對象數據(如集合等)、關係數據、DataSet對象數據和XML結構的數據(如XML文件)。數據庫
1.什麼是Linq?編程
「查詢」是一組指令,使用這些指令能夠從一個或是對個給定的數據源中檢索數據,並返回指定表現形式的結果。Linq也是一種查詢,它集成於.NET3.5之中,能夠爲C#等編程語言提供強大的方便的查詢功能,並與其整合一體,成爲Visual Studio 2008中的一組全新的功能。數組
Linq 也是一種查詢技術。下面咱們使用Linq從以整數集合中查詢數值小於10的元素。其中,編程語言
From:子句描述被查詢的數據源;學習
Where:子句指定元素所知足的過濾條件;this
Select:子句制定查詢結果的表現形式。spa
List
<
int
>
myDataSource
=
new
List
<
int
>
{
1
,
2
,
23
,
4
,
15
,
26
,
15
,
5
,
45
,
61
,
8
,
9
};
var result
=
from i
in
myDataSource
where
i
<
10
select i;
反思:傳統編程中,查詢數據每每須要將字符串嵌入到應用程序中進行查詢操做,這樣通常不會檢查被查詢的數據類型。Linq使得查詢操做成爲編程語言的一部分,能夠象書寫代碼同樣,方便的建立查詢和表達式。設計
2. Linq基本組成組件
Linq是一項突破性創新技術,將數據、對象和平常編程語言之間架起一座橋樑。幾乎能夠查詢和操做任何存儲形式的數據。
(1) Linq to Sql組件:能夠查詢關係型數據庫的數據,並能夠提供其餘操做,如檢索、插入、修改、刪除、排序、聚合、分區等。
(2) Linq to DataSet組件:查詢DataSet對象中的數據。
(3) Linq to Object組件:能夠查詢IEnumerable或是IEnumerable<T> 集合對象,即可以查詢任何能夠枚舉的集合,如數組(Array和ArrayList)、泛型字典Dictinary<T>等,以及用戶自定義的集合,而不須要使用Linq提供程序或API。
(4) Linq to XML組件:查詢和操做XML結構的數據。
3. 開發環境
關於開發環境,簡單補充以下:
要開發ASP.NET 3.0/3.5Web 應用程序,則須要安裝Microsoft Visual Studio 2008集成開發環境(IDE)。由於Linq被.NET 3.5所支持,故如果建立Linq的Web應用程序或是Windows Form應用程,必須使用.NET 3.5.
4. 第一個使用Linq的web應用程序
(1)建立一個WebSite,命名 Linq_Sample_1;
(2)建立一個整形數組intDataSource,長度100,for初始化該數組(0~99);
(3)建立Linq查詢表達式,從數組中查詢小於20的元素。並保存的query變量中。
protected
void
Page_Load(
object
sender, EventArgs e)
{
if
(
!
this
.IsPostBack)
{
LinqQueryData();
}
}
public
void
LinqQueryData()
{
int
[] intDataSource
=
new
int
[
100
];
for
(
int
i
=
0
; i
<
100
; i
++
)
{
intDataSource[i]
=
i;
}
//
建立Linq查詢語句
var query
=
from i
in
intDataSource
where
i
<
20
select i;
foreach
(var q
in
query)
{
Response.Write(q.ToString()
+
"
<br/>
"
);
}
}
5. 四個重要接口
進一步學習Linq須要熟悉Linq最基本的四個接口。即:IEnumerable、IEnumerable<T>、IQueryable和IQueryable<T>,全部支持linq查詢的對象,都必須直接或是間接是想IEnumerable接口。
關於四個類的詳細設計,你能夠參閱MSDN。
6. 與Linq相關的命名空間
.NET 3.5 提供了多個與Linq相關的命名空間,如:
(1) System.Linq 命名空間,提供支持使用Linq進行查詢的類和接口,如Enumerable類、Queryable類、IQueryable 接口、IQueryable<T>接口、IorderedQueryable接口、IorderQueryable<T>接口等。
(2) System.Data.Linq 命名空間,提供與Linq to Sql相關的類、結構、接口和枚舉,如Table<T>類,EntityRef<T>結構、EntitySet<T>結構、IExecuteResult接口、IFunctionResult接口、IMultipleResults接口、ISingleResult<T>接口等。
(3) System.Xml.Linq命名空間,提供與Linq to XML相關的類和枚舉,如XDocument類、XElement類、XAttribute類、XDeclaration類、XName類、XNamespace類、XText類等。
7. Linq 查詢的優點
這裏提早強調是,爲便於講解或是體驗,定義數據庫MyLinqDB爲本學習筆記貫穿始終的數據庫名稱。
1)、查詢集合中的數據
傳統方法爲使用for或是foreach語句,而Linq使用查詢表達式查詢集合中的數據。書寫簡潔、容易添加判斷條件。
7.1.1 Foreach 查詢集合
private
void
OldArrayQuery()
{
string
[] datasource
=
new
string
[
10
];
for
(
int
i
=
0
; i
<
10
; i
++
)
{
datasource[i]
=
"
LINQ
"
+
i.ToString().PadLeft(
5
,
'
0
'
);
}
//
建立一動態數組,保存查詢結果
ArrayList result
=
new
ArrayList();
foreach
(
string
s
in
datasource)
{
int
index
=
Int32.Parse(s.Substring(
4
));
if
(index
%
2
==
0
)
{
result.Add(s);
}
}
foreach
(
string
s
in
result)
{
Response.Write(s
+
"
<br/>
"
);
}
}
7.1.2 Linq查詢數組
private
void
LinqArrayQuery()
{
string
[] datasource
=
new
string
[
10
];
for
(
int
i
=
0
; i
<
10
; i
++
)
{
datasource[i]
=
"
LINQ
"
+
i.ToString().PadLeft(
5
,
'
0
'
);
}
var result
=
from s
in
datasource
let index
=
int
.Parse(s.Substring(
4
))
where
index
%
2
==
0
select s;
foreach
(
string
s
in
result)
{
Response.Write(s
+
"
<br/>
"
);
}
}
反思:
Foreach語句每每與查詢條件相互分隔,代碼相對繁瑣;Linq,一個查詢表達式便可實現查詢和配置查詢兩個功能。代碼相對較少,集成度也較高。
7.2.1查詢數據庫中的數據
傳統的方法爲使用SQL語句或是存儲過程直接進行查詢;而是用Linq查詢數據庫中的數據,須要爲該數據庫建立實體類,而後使用Linq查詢表達式查詢相關數據。
傳統的方法無非建立數據庫鏈接對象(Connection),查詢語句」Select * from Mytable」,或有參數或無參數,接着再建立一個SQL語句的命令對象Command,調用ExecuteReader()方法讀取數據,並保存在變量中供使用。
具體實現代碼這裏不作贅述。
Linq查詢數據庫中的數據的過程:
(1) 爲MyLinqDB數據庫建立DBML文件LinqDB.dbml,併爲表建立實體類 。
(2) 建立LinqDB數據庫的數據上下文類的實例,鏈接字符串保存在strConn。
(3) 建立查詢表達式,將查詢結果存在results變量中。
(4) 使用foreach語句顯示results變量中的查詢結果。
代碼比較以下:
(1) 傳統方法:
private
void
OldSQLQuery()
{
//
建立數據庫鏈接
SqlConnection con
=
new
SqlConnection(strCon);
//
建立SQL語句、
string
cmdText
=
"
select * from Products
"
;
//
建立SqlCommand 對象 執行SQL 命令
SqlCommand cmd
=
new
SqlCommand(cmdText, con);
con.Open();
//
執行查詢操做
SqlDataReader reader
=
cmd.ExecuteReader();
while
(reader.Read())
{
if
(reader[
"
ProductName
"
].ToString().Length
>
6
)
{
Response.Write(reader[
"
ProductName
"
].ToString()
+
"
</br>
"
);
}
}
reader.Close();
con.Close();
}
(2) Linq to SQL :
private
void
LinqSQLQuery()
{
LinqDBMLDataContext db
=
new
LinqDBMLDataContext(strCon);
var results
=
from p
in
db.Products
where
p.ProductName.Length
>
10
select p;
foreach
(var i
in
results)
{
Response.Write(i.ProductName
+
"
</br>
"
);
}
}
代碼簡潔明朗。
3)、查詢DataSet對象中的數據
傳統方法每每須要使用foreach語句等,遍歷讀取。Linq則使用查詢表達式查詢對象中的數據。
代碼比較以下:
(1) 傳統方法:
private
DataSet GetDataSet()
{
SqlConnection con
=
new
SqlConnection(strCon);
string
cmdText
=
"
select * from products
"
;
SqlDataAdapter da
=
new
SqlDataAdapter(cmdText, con);
con.Open();
DataSet ds
=
new
DataSet();
da.Fill(ds,
"
Product
"
);
con.Close();
return
ds;
}
private
void
OldDataSetQuery()
{
DataSet ds
=
GetDataSet();
foreach
(DataRow row
in
ds.Tables[
0
].Rows)
{
if
(row[
"
ProductName
"
].ToString().Length
>
10
)
{
Response.Write(row[
"
ProductName
"
].ToString()
+
"
<br/>
"
);
}
}
}
(2) Linq to DataSet
private
void
LinqDataSetQuery()
{
DataSet ds
=
GetDataSet();
var results
=
from p
in
ds.Tables[
0
].AsEnumerable()
where
p.Field
<
string
>
(
"
ProductName
"
).Length
>
10
select p;
foreach
(var v
in
results)
{
Response.Write(v.Field
<
string
>
(
"
ProductName
"
).ToString()
+
"
<br/>
"
);
}
}
4)、查詢XML文件
傳統的方法每每使用XPath。Linq使用查詢表達式查詢XML文件中的數據。
代碼比較以下:
(1) 傳統方法
private
string
xmlString
=
"
<Books>
"
+
"
<Book ID=\
"
101
\
"
>
"
+
"
<No>0001</No>
"
+
"
<Name>Book 0001</Name>
"
+
"
<Price>120</Price>
"
+
"
<Remark>This is a book 0001.</Remark>
"
+
"
</Book>
"
+
"
<Book ID=\
"
102
\
"
>
"
+
"
<No>0002</No>
"
+
"
<Name>Book 0002</Name>
"
+
"
<Price>120</Price>
"
+
"
<Remark>This is a book 0002.</Remark>
"
+
"
</Book>
"
+
"
<Book ID=\
"
103
\
"
>
"
+
"
<No>0003</No>
"
+
"
<Name>Book 0003</Name>
"
+
"
<Price>120</Price>
"
+
"
<Remark>This is a book 0003.</Remark>
"
+
"
</Book>
"
+
"
</Books>
"
;
private
void
OldXMLQuery()
{
XmlDocument doc
=
new
XmlDocument();
doc.LoadXml(xmlString);
string
path
=
"
/Books/Book
"
;
XmlNodeList nodeList
=
doc.SelectNodes(path);
foreach
(XmlNode node
in
nodeList)
{
foreach
(XmlNode n
in
node.ChildNodes)
{
if
(n.InnerXml
==
"
Book 0002
"
)
{
Response.Write(node.LocalName
+
node.Attributes[
"
ID
"
].Value
+
"
<br/>
"
);
}
}
}
}
(2) Linq to XML
private
void
LinqXMLQuery()
{
XElement xe
=
XElement.Parse(xmlString);
var results
=
from x
in
xe.Elements()
where
(
string
)x.Element(
"
Name
"
)
==
"
Book 0002
"
select x;
foreach
(var e
in
results)
{
Response.Write(e.Name.LocalName
+
e.Attribute(
"
ID
"
).Value
+
"
<br/>
"
); } }