LInq是Language Integrated Query的简称,它是微软在.net framework 3.5里面新加入的特性,用以简化查询查询操作。它主要包含了3块,Linq to Object、Linq to SQL、Linq to XML,其中Linq to Object和对于对象的查询,Linq to XML则又提供了对XML格式数据的检索、设置等功能,其中值得关注的Linq to SQL是我们要重点掌握的,因为它改变了我们传统的对于SQL操作的认识。
一、Linq to Object
先上一段代码:
1
2
3
4
5
6
7
|
string
[] contries =
new
string
[] {
"china"
,
"russia"
,
"american"
,
"spain"
,
"japan"
,
"china"
};
var
query =
from
c
in
contries
select
c;
//Linq to object
IEnumerator enumerator = query.GetEnumerator();
while
(enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
|
注意Linq to Object的语法,from c in contries select c ; // 这里的c任意起名,in后面的contries 为数组对象或者是列表、集合等对象,select c 与前面的c保持一致。这是Linq强大的地方,试想我们以前要想查询数组里面的每一个元素要写一层for循环然后循环输出。这里似乎看不出什么明显优势的地方,我们继续往下看。
1
2
3
|
var
query =
from
c
in
contries
select
c;
替换为:
var
query =
from
c
in
contries.Distinct()
where
c.Length == 5
orderby
c
ascending
select
c;
|
我们会发现利用linq可以很容易的像利用sql语句一样查询、排序,如果利用原始的技术可能要多些好几行代码!
再举个例子。
这是论坛某个坛友发的帖子,问如何用Linq进行分组查询。见linq分组统计。
我在里面给出了解答,当然了里面的List完全可以是从数据库中获取,我简单模拟了一下,代码如下。
定义1个实体类:
1
2
3
4
5
6
7
8
9
10
11
|
public
class
Product
{
public
Product(
string
province, Int32 value)
{
this
.Province = province;
this
.Value = value;
}
public
string
Province {
get
;
set
; }
public
Int32 Value {
get
;
set
; }
}
|
然后在Main函数中输入:
1
2
3
4
5
6
7
8
9
10
11
|
var
result =
from
p
in
list.AsEnumerable()
group
p
by
p.Province
into
g
select
new
{
g.Key,
SumValue = g.Sum(p => p.Value)
};
result.ToList().ForEach((i) =>
{
Console.WriteLine(i.Key +
":"
+ i.SumValue);
});
|
可以得到分组统计的结果。
再附一个简单排序的例子。linq排序
二、Linq to SQL
这是Linq技术的重头戏,当然现在有了EntityFramework等技术,但是我们还是可以关注一下。
我们新建两张表,很简单。
然后在项目中新建一个Linq to SQL类,切换到设计界面。同时打开服务资源管理器,添加数据连接,连接到数据库。拖动classInfo和studentInfo两张表到Linq to SQL类文件的设计界面,我们会发现关系替我们都准备的好好的。
OK,这时就可以写相应代码,进行添加操作了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
DataClasses1DataContext datacontext =
new
DataClasses1DataContext();
classInfo classInfo =
new
classInfo()
{
classId = 1,
className =
"grade1"
};
datacontext.classInfo.InsertOnSubmit(classInfo);
studentInfo studentInfo =
new
studentInfo()
{
studentId =
"001"
,
studentName =
"liming"
,
classId = 1
};
datacontext.studentInfo.InsertOnSubmit(studentInfo);
datacontext.SubmitChanges();
|
这样就添加了1条班级记录和1条学生记录。
如果我们要删除一条学生记录怎么办?举个例子,键入如下代码:
1
2
3
4
|
DataClasses1DataContext datacontext =
new
DataClasses1DataContext();
studentInfo studentInfo = datacontext.studentInfo.Single(c => c.studentName ==
"liming"
);
datacontext.studentInfo.DeleteOnSubmit(studentInfo);
datacontext.SubmitChanges();
|
这样就把liming这个学生记录给删除了,很简单吧?
好,现在我们修改这个学生记录,把名字改成zhang3。
1
2
3
4
|
DataClasses1DataContext datacontext =
new
DataClasses1DataContext();
studentInfo studentInfo = datacontext.studentInfo.Single(c => c.studentName ==
"liming"
);
studentInfo.studentName =
"zhang3"
;
//直接赋新的值
datacontext.SubmitChanges();
//提交更改就可以了
|
补充一点很重要的,就是如何用linq to sql来进行查询操作。
前面的Single其实就是一种查询操作,返回单个对象。
直接上一个linq带条件的分页查询实例:
1
2
3
4
5
6
7
8
9
10
11
12
|
DataClasses1DataContext datacontext =
new
DataClasses1DataContext();
var
singleStudent =
from
s
in
datacontext.studentInfo
where
s.studentName !=
"zhang3"
orderby
s.classInfo
descending
select
s;
IList<studentInfo> studentList = singleStudent.Skip(pageSize * (pageNumber - 1)).Take(pageSize).ToList();
foreach
(studentInfo student
in
studentList)
{
Console.WriteLine(
"studentId:"
+ student.studentId +
"studentName:"
+ student.studentName);
}
|
三、Linq to XML
以前我们操作XML一般都用XmlDocument、XmlReader等核心类去处理,关于这个我在点击打开链接这个帖子中已经简单总结了一把。这里我们看看Linq是怎么处理XML的。
1、创建XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
XElement contacts =
new
XElement(
"Students"
,
new
XElement(
"Student"
,
new
XElement(
"Name"
,
"Xiao Ming"
),
new
XElement(
"Phone"
,
"99599"
,
new
XAttribute(
"Type"
,
"Home"
)),
new
XElement(
"phone"
,
"010-99599"
,
new
XAttribute(
"Type"
,
"Work"
)),
new
XElement(
"Address"
,
new
XElement(
"Street"
,
"123 Street"
),
new
XElement(
"City"
,
"123 City"
),
new
XElement(
"State"
,
"1"
),
new
XElement(
"Postal"
,
"0000000"
)
)
)
);
contacts.Save(
"test.xml"
);
|
你会发现,你只要记住XElement这一个核心类就可以使用Linq创建xml,而且编码的方式很轻松,就是在表达一个xml的层级关系。
效果如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
Students
>
<
Student
>
<
Name
>Xiao Ming</
Name
>
<
Phone
Type
=
"Home"
>99599</
Phone
>
<
phone
Type
=
"Work"
>010-99599</
phone
>
<
Address
>
<
Street
>123 Street</
Street
>
<
City
>123 City</
City
>
<
State
>1</
State
>
<
Postal
>0000000</
Postal
>
</
Address
>
</
Student
>
</
Students
>
|
2、查询XML
还是用上面生成的XML来做测试,键入如下代码:
1
2
3
4
5
6
7
8
9
|
XElement root = XElement.Load(
"test.xml"
);
IEnumerable address =
from
el
in
root.Elements(
"Student"
).Elements(
"phone"
)
where
el.Attribute(
"Type"
).Value ==
"Work"
select
el;
foreach
(XElement el
in
address)
{
Console.WriteLine(el.Value);
}
|
输出:010-99599。
四、Linq to DataTable
意思跟Linq to Object是一样的,应该属于Linq to Object的范畴,这里单独拿出来,分享一下。
举个例子,对两个DataTable的数据进行合并,原贴见:两个DataTable合并列。
先构造两个DataTable。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
DataTable A =
new
DataTable();
A.Columns.Add(
"NameNumber"
,
typeof
(
string
));
A.Columns.Add(
"Type"
,
typeof
(
string
));
DataRow drA =
null
;
drA = A.NewRow();
drA[
"NameNumber"
] =
"111"
;
drA[
"Type"
] =
"Y"
;
A.Rows.Add(drA);
drA = A.NewRow();
drA[
"NameNumber"
] =
"222"
;
drA[
"Type"
] =
"N"
;
A.Rows.Add(drA);
DataTable B =
new
DataTable();
B.Columns.Add(
"NameNumber"
,
typeof
(
string
));
B.Columns.Add(
"Name"
,
typeof
(
string
));
B.Columns.Add(
"Address"
,
typeof
(
string
));
DataRow drB =
null
;
drB = B.NewRow();
drB[
"NameNumber"
] =
"111"
;
drB[
"Name"
] =
"张三"
;
drB[
"Address"
] =
"上海"
;
B.Rows.Add(drB);
drB = B.NewRow();
drB[
"NameNumber"
] =
"222"
;
drB[
"Name"
] =
"李四"
;
drB[
"Address"
] =
"北京"
;
B.Rows.Add(drB);
|
然后我们通过Linq to DataTable进行合并。
1
2
3
4
5
6
7
8
9
10
|
var
result =
from
p
in
A.AsEnumerable()
from
q
in
B.AsEnumerable()
where
p.Field<
string
>(
"NameNumber"
) == q.Field<
string
>(
"NameNumber"
)
select
new
{
NameNumber = p.Field<
string
>(
"NameNumber"
),
Type = p.Field<
string
>(
"Type"
),
Address = q.Field<
string
>(
"Address"
)
};
result.ToList().ForEach(x => Console.WriteLine(x.NameNumber +
"-"
+ x.Type +
"-"
+ x.Address));
|
效果图下:
本文转自 guwei4037 51CTO博客,原文链接:http://blog.51cto.com/csharper/1344191