首页 > 代码库 > .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#语言)