首页 > 代码库 > .NET访问数据库的两种方式(C#语言)
.NET访问数据库的两种方式(C#语言)
一、直接使用C#操作数据库的类库ADO.NET
ADO.NET使用Connection对象来连接数据库,使用Command或DataAdapter
对象来执行SQL语句,并将执行的结果返回给DataReader或DataAdapter,然后
再使用取得的DataReader或者DataAdapter对象操作数据结果。
二、Entity Framework
Entity Framework 实体框架是微软的一个ORM框架。是支持面向数据的软件开
发应用程序。我们一般配合linq和lambda表达式使用。
ORM((Object Relational Mapping对象关系映射)指的是面向对象的对象模型和
关系型数据库的数据结构之间的互相转换。(表实体跟表之间的相互转换)
LINQ查询:当我们使用linq查询时,转到定义会调到Queryable 类, 那么也就是
说,这个类封装了linq所有查询的方法,提供一组用于查询实现 IQueryable<T>
的数据结构的 静态方法。
IQueryable和IList一样,是用于接收一组数据的集合, IQeurable
(IQuerable<T>)不会立即在内存里创建持久数据,只有遍历它(如通过
foreach)、把它转换成List等情况下才会向内存加载数据,它可以实现“延期执
行”,如果当前被加载的实体有关联实体(associations),此关联实体可被接下
来的访问加载。
Ilist-继承顺序如下:
Ilist->ICollection ->IEnumerable
IEnumerable它允许开发人员定义foreach语句功能的实现并支持非泛型方法的简
单的迭代
同样的IQueryable也继承自IEnumerable<T>这一泛型接口
Queryable类提供了扩展的基本查询方法:Where,Select
select提供方法如下:
public static IQueryable<TResult> Select<TSource, TResult>(this
IQueryable<TSource> source, Expression<Func<TSource, TResult>>
selector);
where提供的方法如下:
public static IQueryable<TSource> Where<TSource>(this
IQueryable<TSource> source, Expression<Func<TSource, bool>>
predicate);
public static IQueryable<TSource> Where<TSource>(this
IQueryable<TSource> source, Expression<Func<TSource, int, bool>>
predicate);
Lambda表达式
(1)源起.net的设计者发现在使用匿名方法时,仍旧有一些多余的字母或单词的编码工作
比如delegate关键字于是进一步简化了匿名方法的写法。
(2)使用
List<int> arr = new List<int>() { 1, 2, 3, 4, 5, 6, 7 };
arr.ForEach(new Action<int>(delegate(int a) { Console.WriteLine
(a); }));
arr.ForEach(new Action<int>(a => Console.WriteLine(a)));
匿名方法的代码如下:
delegate(int a) { Console.WriteLine(a); }
使用lambda表达式的代码如下:
a => Console.WriteLine(a)
这里解释一下这个lambda表达式
<1>
a是输入参数,编译器可以自动推断出它是什么类型的,
如果没有输入参数,可以写成这样:
() => Console.WriteLine("ddd")
<2>
=>是lambda操作符
<3>
Console.WriteLine(a)是要执行的语句。
如果是多条语句的话,可以用{}包起来。
如果需要返回值的话,可以直接写return语句
LINQ
1.查询操作符
(1)源起
.net的设计者在类库中定义了一系列的扩展方法
来方便用户操作集合对象
这些扩展方法构成了LINQ的查询操作符
(2)使用
这一系列的扩展方法,比如:
Where,Max,Select,Sum,Any,Average,All,Concat等
都是针对IEnumerable的对象进行扩展的
也就是说,只要实现了IEnumerable接口,就可以使用这些扩展方法
来看看这段代码:
List<int> arr = new List<int>() { 1, 2, 3, 4, 5, 6, 7 };
var result = arr.Where(a => { return a > 3; }).Sum();
Console.WriteLine(result);
Console.ReadKey();
这段代码中,用到了两个扩展方法。
(3)好处
上面的代码中
arr.Where(a => { return a > 3; }).Sum();
这一句完全可以写成如下代码:
(from v in arr where v > 3 select v).Sum();
而且两句代码的执行细节是完全一样的
大家可以看到,第二句代码更符合语义,更容易读懂
第二句代码中的where,就是我们要说的查询操作符。
(4)标准查询操作符说明
<1>过滤
Where
用法:arr.Where(a => { return a > 3; })
说明:找到集合中满足指定条件的元素
OfType
用法:arr.OfType<int>()
说明:根据指定类型,筛选集合中的元素
<2>投影
Select
用法:arr.Select<int, string>(a => a.ToString());
说明:将集合中的每个元素投影的新集合中。上例中:新集合是
一个IEnumerable<String>的集合
SelectMany
用法:arr.SelectMany<int, string>(a => { return new
List<string>() { "a", a.ToString() }; });
说明:将序列的每个元素投影到一个序列中,最终把所有的序列
合并
<3>还有很多查询操作符,请翻MSDN,以后有时间我将另起一篇文
章把这些操作符写全。
2.查询表达式
(1)源起
上面我们已经提到,使用查询操作符表示的扩展方法来操作集合;
虽然已经很方便了,但在可读性和代码的语义来考虑,仍有不足;
于是就产生了查询表达式的写法。
虽然这很像SQL语句,但他们却有着本质的不同。
(2)用法
from v in arr where v > 3 select v
这就是一个非常简单的查询表达式
(3)说明:
先看一段伪代码:
from [type] id in source
[join [type] id in source on expr equals expr [into
subGroup]]
[from [type] id in source | let id = expr | where condition]
[orderby ordering,ordering,ordering...]
select expr | group expr by key
[into id query]
<1>第一行的解释:
type是可选的,
id是集合中的一项,
source是一个集合,
如果集合中的类型与type指定的类型不同则导致强制类型转化
<2>第二行的解释:
一个查询表达式中可以有0个或多个join子句,
这里的source可以是一个全新的集合,可以不等于第一句中的
source
expr可以是一个表达式
[into subGroup] subGroup是一个中间变量,
它继承自IGrouping,代表一个分组,也就是说“一对多”里的
“多”
可以通过这个变量得到这一组包含的对象个数,以及这一组对象
的键
比如:
from c in db.Customers
join o in db.Orders on c.CustomerID
equals o.CustomerID into orders
select new
{
c.ContactName,
OrderCount = orders.Count()
};
<3>第三行的解释:
一个查询表达式中可以有1个或多个from子句
一个查询表达式中可以有0个或多个let子句,let子句可以创建一
个临时变量
比如:
from u in users
let number = Int32.Parse(u.Username.Substring
(u.Username.Length - 1))
where u.ID < 9 && number % 2 == 0
select u
一个查询表达式中可以有0个或多个where子句,where子句可
以指定查询条件
<4>第四行的解释:
一个查询表达式可以有0个或多个排序方式
每个排序方式以逗号分割
<5>第五行的解释:
一个查询表达式必须以select或者group by结束
select后跟要检索的内容
group by 是对检索的内容进行分组
比如:
from p in db.Products
group p by p.CategoryID into g
select new { g.Key, NumProducts = g.Count()};
<6>第六行的解释:
最后一个into子句起到的作用是
将前面语句的结果作为后面语句操作的数据源
比如:
from p in db.Employees
select new
{
LastName = p.LastName,
TitleOfCourtesy = p.TitleOfCourtesy
} into EmployeesList
orderby EmployeesList.TitleOfCourtesy ascending
select EmployeesList;
.NET访问数据库的两种方式(C#语言)