Evil 域

当Evil遇上先知

导航

ADO.NET Entity Framework 试水——语言

Posted on 2008-09-03 20:32  Saar  阅读(5099)  评论(25编辑  收藏  举报

毋庸置疑,在数据库访问方面,SQL是名符其实的标准。但是,SQL却不能直接操作实体。于是,在实体与数据库访问之间,就出现了一道鸿沟。Entity SQL(以下简称eSQL)的出现,即用于填补这两者之间的不匹配问题。通过本文,我们将了解到eSQL的一般使用方法以及两套使用的接口。

 

一、要完成本文中的实例,您需要作如下准备:

  1. Visual Studio 2008.NET Framework 3.5升级到SP1点击转到升级地址
  2. 安装SQL SERVER 2005VS 2008中自带的EXPRESS版的SQL SERVER应该也可以用。
  3. 下载并附加数据库:点击下载DemoDbV2
  4. 创建一个VB Console Application,并且取一个合适的名字(例如:EntitySQL之类的)。注意,目标Framework要设置成3.5版。

当前数据库Notebook表中数据如下:

 

1

 

二、为什么要使用eSQL?

 

eSQL自出生之日起,日子就不怎么好过。为什么这么说?大家针对数据库访问,习惯性的想到SQL;而在EF正式发布前,大家已经对LINQ有所了解,因此,针对实体的访问,大家首先想到的应该是LinQ。那么,微软为什么还要推出eSQL?它相对于SQLLinQ有什么优势?

相对于SQLeSQL提供了对实体的很好的支持——这是SQL所不具备的(历史原因 ^_^)。SQL查询出来的是行,eSQL,则可以直接查询出实体集。eSQL直接支持EDM中的类型,而SQL不支持(废话,有SQL的时候,EDM还没有出世呢)……

相对于自己的哥哥——LinQeSQL显得更为灵活。由于eSQL的查询语句是个字符串,因此,其十分易于处理。举个简单的例子,如果我要写一个方法,传入排序的属性名称,返回一个按照此属性排序好的实体集,要用LinQ实现,恐怕有点麻烦,因为,其ORDER BY后面,需要跟一个实体类的属性;然而,在eSQL里,这简单是轻而易举的事,只要写上一个eSQL语句,把排序位置留为{0},然后进行字符串替换,这一功能就完成了——好像比较难说明白,没有关系,后面的示例代码里有相关的部分。

总之,一句话,eSQL是个好东东——因为它是本文介绍的主角^_^。至于到底是不是那么一回事儿,大家可以试一下本文的示例,然后,根据自己的理解来酌情运用。

 

三、eSQL的使用方法

 

EFeSQL提供了两套接口:Entity Command接口和ObjectQuery接口。让我们首先来了解一下这两套接口的使用模式:

  • Entity Command接口:

'Using EntityCommand Interface

Private Sub QueryESql1()

    Using eConn As New EntityConnection(ConnString)

        Dim myQuery = "{0,1,2,3}"

        Using cmd As New EntityCommand(myQuery, eConn)

            eConn.Open()

            Using reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)

                While (reader.Read())

                    Console.WriteLine(reader.GetValue(0))

                End While

            End Using

        End Using

    End Using

End Sub

首先,通过预先配置好的连接字符串,创建一个EntityConnection类型的连接eConn

然后,定义查询语句;

第三步,通过连接和查询语句,创建一个EntityCommand的对象cmd

第四步,打开连接,读取数据。

这一接口形式,更接近于传统的ADO.NET的调用形式。

  • ObjectQuery接口:

'Using ObjectQuery(Of T) interface

Private Sub QueryESql2()

    Using objContext As New ObjectContext(ConnString)

        Dim myQuery = "NotebookEntities.Notebook"

        objContext.Connection.Open()

        For Each aLaptop As Notebook In New ObjectQuery(Of Notebook)(myQuery, objContext)

            Console.WriteLine(aLaptop.Brand & " " & aLaptop.Type)

        Next

    End Using

End Sub

第一步,通过连接字符串,创建一个ObjectContext对象objContext

第二步,字义查询语句;

第三步,打开连接,查询数据。

这个形式,比较充分的利用了eSQL对实体类形的支持。

 

四、实例

1. 从数据库获取全部的笔记本电脑数据,显示其品牌、型号。

Entity Command接口实现方法:

'Using EntityCommand Interface

Private Sub QueryESql1()

    Using eConn As New EntityConnection(ConnString)

        Dim myQuery = "SELECT n.Brand, n.Type FROM NotebookEntities.Notebook as n"

        Using cmd As New EntityCommand(myQuery, eConn)

            eConn.Open()

            Using reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)

                While (reader.Read())

                    Console.WriteLine(reader.GetValue(0) & " " & reader.GetValue(1))

                End While

            End Using

        End Using

    End Using

End Sub

我们通过写一个eSQL语句,从NotebookEntities实体容器的Notebook实体集中,把所有的实体一行行取出,并通过DbDataReader实现的对象将其输出。运行结果如下:

2

 

ObjectQuery接口则更加直接:

'Using ObjectQuery(Of T) interface

Private Sub QueryESql2()

    Using objContext As New ObjectContext(ConnString)

        Dim myQuery = "NotebookEntities.Notebook"

        objContext.Connection.Open()

        For Each aLaptop As Notebook In New ObjectQuery(Of Notebook)(myQuery, objContext)

            Console.WriteLine(aLaptop.Brand & " " & aLaptop.Type)

        Next

    End Using

End Sub

通过一个For Each循环,对ObjectQuery(Of Notebook)返回的实体集进行遍历,每一个实体的BrandType属性输出到屏幕上。输出结果与图2相同。

 

2. SELECT VALUE

在上面两个查询中,通过eSQL返回出来的,仍然是一个ROW对象。这就是说,即使我们写下面这样一条eSQL语句:

SELECT n.Brand FROM NotebookEntities.Notebook AS n

输出结果时,我们仍然需要写上reader.GetValue(0)来处理。

然而,很多时候,我们需要仅对一个值进行操作(这个值可以是简单的一个整数或者是一个复杂对象、一个实体……)。这时,eSQL引入了新关键字VALUE。我们来看看如何选出一个实体值:

'Select & Select VALUE

Private Sub QueryESql3()

    Using eConn As New EntityConnection(ConnString)

        Using objContext As New ObjectContext(eConn)

            Dim myQuery = "SELECT VALUE n FROM NotebookEntities.Notebook AS n"

            objContext.Connection.Open()

            For Each aLaptop As Notebook In New ObjectQuery(Of Notebook)(myQuery, objContext)

                Console.WriteLine(aLaptop.Brand & " " & aLaptop.Type)

            Next

        End Using

    End Using

End Sub

通过添加一个简单的关键字VALUE,通过eSQL返回出来的,就是一个值而非一个ROW了。

 

3.内建的分页支持

自定义分页一直是一个企业应用中常用的功能,同时也是一个比较费时又容易出问题的地方。现在,eSQL内建了对自定义分页的支持。使用方法非常简单,只需要两个参数:SKIPLIMIT

其中,SKIP表示需要跳过的行数。例如,SKIP 2则从第三行进行输出,在分页中可以作为rowStartIndex来使用;LIMIT则表示需要输出的最大行数,在分页中可以作为pageSize来使用。我们来看一个例子:

'Build in paging

''' <summary>

''' Query data with build in paging

''' </summary>

''' <param name="startIndex">Start entity index start from 0</param>

''' <param name="pageSize"></param>

''' <remarks></remarks>

Private Sub QueryESql4(Optional ByVal startIndex As Integer = 0, Optional ByVal pageSize As Integer = 10)

    Using eConn As New EntityConnection(ConnString)

        Using objContext As New ObjectContext(eConn)

            Dim myQuery = "SELECT VALUE n FROM NotebookEntities.Notebook AS n ORDER BY n.Brand SKIP {0} LIMIT {1}"

            myQuery = String.Format(myQuery, startIndex, pageSize)

            For Each aLaptop In New ObjectQuery(Of Notebook)(myQuery, objContext)

                Console.WriteLine(aLaptop.Brand & " " & aLaptop.Type)

            Next

        End Using

    End Using

End Sub

在这段代码时,我们通过把startIndexpageSize作为参数传入,替换查询语句中SKIPLIMIT后面的值,来达到分页输出的目的。需要注意一下的是,SKIPLIMIT,需要依赖ORDER BY。因此,必须针对某一属性进行排序后,方可使用SKIPLIMIT来进行分页。当传入参数(2,2)时,输出结果如下:

3

 

 

五、示例代码下载

 

点击下载

 

==返回索引==