zoukankan      html  css  js  c++  java
  • 数据库ADONET排序、搜索和筛选

     

    排序、搜索和筛选

    如何使用一个值或一组值来查找DataTable中的特定行?

    如何使用筛选程序是只有满足条件的行可见?

    如何控制要访问或者显示的行的排序顺序?

    可以使用:

    DataRowCollection类的Find方法,DataTable类是Select方法,DataView对象和DataRowView对象。

    1           使用DataTable对象的搜索和筛选功能

    DataTable对象公开了两个方法,它们可以用来根据搜索标准查找数据。

    Find方法,根据主键值来查找数据。

    Select方法,类似于筛选程序,根据更灵活的搜索标准返回多行数据。

    1.1         根据主键值查找行

    查询数据库以获取信息时,通常都会希望,根据其主键列的值,来获取特定行的数据。

    可以使用以下查询:

    Select CustomerID,CompanyName,ContactName,Phone from Customers where CustomerID=”ALFKI”

    还可以根据行的主键值,在DataTable中查找DataRow

    尽管Find方法是为DataTable对象设计的,但是,它实际上是由DataRowCollection类公开的。

    Find方法接受一个包含要查询的行的主键值作为参数,因为主键值是惟一的,所以Find方法只能返回一行DataRow

    Dim strConn, strSql as string

    strConn=”Provider=SQLOLEDB;Data Source=(local)"NetSDK; Initial Catalog=Northwind;
    Trusted_Connection=Yes;”

    strSql=”select CustomerID,CompanyName,ContactName,Phone from Customers”

    Dim da as New Oledb.OledbDataAdapter(strSql,strConn)

    Dim tbl as new DataTable

    Da.fill(tbl)

    Tbl.PrimaryKey=new DataColumn(){tbl.Columns(“CustomerID”)}

    Dim row as DataRow=tbl.Rows.Find(“ALFKI”)

    If row Is Nothing then

         Console.WriteLine(“Row Not Found.”)

    Else

         Console.WriteLine(Row(“CompanyName”))

    End IF

    注意:

    从技术角度来说,DataTable可以包含拥有相同主键值的多个行。

    如果,将DataSetEnforceConstraints属性设置为假False,那么即使违反了主键约束,DataTable也不会抛出异常。

    Find方法将返回找到的所有目标主键值的行。

    Find方法,针对DataTable的主键包含多个DataColumn对象的场景,进行了重载。(组合主键)

    例如:对于【Order Details】表,主键是OrderID/ProductID,查找演示如下:

    Dim strConn,strSql as string

    strConn=”...”

    strSql=”select OrderID,ProductID,Quantity,UnitPrice from [Order Details]”

    dim da as New OleDbDataAdapter(strSql,strConn)

    dim tbl as new DataTable()

    da.Fill(tbl)

    tbl.PrimaryKey=new DataColumn(){tbl.Column(“OrderID”),tbl.Columns(“ProductID”)}

    Dim objCriteria as new Object(){10643,28}

    Dim row as DataRow=tbl.Rows.Find(objCriteria)

    If row Is Nothing Then

         Console.WriteLine(“Row Not Found”)

    Else

         Console.WriteLine(“row(“Quantity”) & “ – “ & row(“UnitPrice”))

    End If

    1.2         执行更动态的搜索

    根据主键值查找行,是很高效的。

    但是,并非所有搜索都是如此直观。

    如果希望查找“位于美国而不在西雅图市的客户”,该怎么办?可以使用Where子句向查询添加一个条件,如下:

    Select CustomerID,CompanyName,ContactName,Phone,City,Country from Customers
    where Country=”USA” AND City <> “Seattle”

    ADONET中,还可以用DataTable对象的Select方法来实现类似的条件查询。

    Dim strConn as string=”Provider=SQLOLEDB;Data Source=(local)"NETSDK;Initial Catalog=Northwind;
    Trusted_Connection=Yes;”

    Dim strSql as String=”select CustomerID,CompanyName,ContactName,Phone,City,Country
    from Customers”

    Dim da as New OleDbDataAdapter(strSql,strConn)

    Dim tbl as new DataTable()

    Da.Fill(tbl)

    Dim arows as DataRow()

    Dim row as DataRow

    Arows=tbl.select(“Country=’USA’ AND City <> ‘Seattle”)

    For Each row in arows

         Console.WriteLine(row(“CompanyName”) & “ – “ & row(“City”) & “ – “ & row(“Country”))

    Next row

    1.3         执行通配符搜索

    ADONET允许使用通配符进行搜索。

    SQL语句中查询CustomerID列是以字母A开始的客户,

    Select CustomerID,CompanyName from Customers where CustomerID LIKE ‘A%’

    可以在字符串的开始或者结尾使用“%*”作为通配符。

    strFilter=”State LIKE ‘New %’” – 将返回在以New开头地区的客户

    strFilter=”State LIKE ‘% Dakota ‘” – 将返回北Dakota和南Dakota的客户

    ADONET不能使用单字母通配符(如:“?”、“_”等)

    1.4         使用分隔符

    在搜索条件中,不能简单的使用“单引号”括住一个字符串,就拉倒了。

    如果是动态构建搜索条件,其中可能会包含“单引号”,那么搜索条件就必须重复它(就是替换成’’),这可以用String类的Replace方法处理。

    strCriteria=”LastName=’” & strLastName.Replace(“ ’ ”, ” ’’ ”) & “’”

    以上是对于“字符串”的处理,那么怎么分隔日期?

    使用pound号(就是#号)括住日期。

    strCriteria=”OrderData>= #01/02/2002# AND OrderDate < #02/02/2002#”

    在某些情况下,需要在搜索条件中分隔列名,原因可能是:

    列名中有空格或其他非字母字符

    列名是保留单词,如LIKESUM等等

    ADONET中,可以使用方括号来作为“列分隔符”。

    strCriteria=”[Space In Name]=3”

    如果在列名中有列分隔符,又怎么办?

    可以在条件字符串的结束分隔符“)”之前用转移字符“"”。比如:列名为Bad]Column[Name,可以这样写:strCriteria=”[Bad"]Column[Name]=5”

    需要特别注意的是,对于C#来说,由于“"”是转义字符,所以实际的字符串应该这样写:

    “[Bad""]Column[Name]=5”

    1.5         使用附加Select方法

    Select方法有一些重载方法,其中的参数包括:

    只提供搜索字符串

    包括排序顺序以及控制要搜索的行的状态参数(例如:仅搜索添加的行或仅搜索被修改的行)

    1.5.1   包括“排序顺序”

    可以通过使用Select重载方法之一,来空值返回的DataRow对象的顺序。

    Sql查询中,可以使用ORDER BY子句,来控制有查询返回的数据的排序顺序。

    例如:

    Select CustomerID,CompanyName,Phone,City from Customers ORDER BY City

    如果是City按照降序排序,则改为ORDER BY City DESC

    DataTableSelect方法,使用示例如下:

    Dim strConn,strSql as String

    strConn=”Provider=SQLOLEDB;Data Source=...;Initial Catalog=Northwind;
    Trusted_Connection=Yes;”

    strSql=”select CustomerID,CompanyName,Phone,City,Country from Customers”

    Dim da as New Oledb.OleDBDataAdapter(strSql,strConn)

    Dim tbl as New DataTable()

    Da.Fill(tbl)

    Dim strCriteria As String=”Country=’USA’ AND City <> ‘Seattle’”

    Dim strSortOrder as string=”City DESC”

    Dim arows as DataRow()=tbl.select(strCriteria,strSortOrder)

    Dim row as DataRow

    For each row in arows

        Console.WriteLine(row(“CompanyName”) & “ – “ & row(“City”) & “ – “ & row(“Country”))

    Next Row

    1.5.2   指定要搜索的行的状态RowState

    使用Select方法的重载版本之一,指定DataViewRowState枚举值作为参数,可以只对特殊状态的行进行搜索。

    举例:希望只检查DataTable中被修改的和被删除的行,使用DataViewRowState枚举类型中的ModifiedOriginalDeleted,将筛选和排序参数使用空串,具体如下:

    Dim dvrs as DataViewRowState

    Dvrs=DataViewRowState.ModifiedOriginal Or DataViewRowState.Deleted

    Dim arows() as DataRow=tbl.Select(“”,””,dvrs)

    Dim row as DataRow

    For Each row in arows

        Console.WriteLine(row(“CompanyName”,DataRowVersion.Original))

    Next Row

    这里要注意的是,被删除的行只能检查行的“原始值Original”。

    2          DataView对象

    DataTableSelect方法,它有两方面的局限性。

    第一:因为它接受动态的搜索条件,所以效率不高;

    第二:WindowsWEB窗体都不支持“绑定”到Select方法的返回值(DataRow数组)

    ADONET针对此问题,提供的解决方案是“DataView”对象。

    ADONET体系中DataTable对象基本等价于数据库中的表,所以可以假设DataView对象类似于视图。

    2.1         DataView对象从DataTable中返回数据

    DataView对象不维护自己的数据副本。

    当通过DataView访问数据时,DataView将返回存储在相应DataTable中的数据。

    类似的,数据库中的视图也是一样,查询一个视图时,数据库会从视图所引用的一个或多个表中返回数据。

    2.2         DataView对象不是SQL查询

    数据库的视图实际上就是一个查询。

    在数据库中创建视图时,要提供数据库将要执行的,返回视图的数据查询:

    CREATE VIEW ViewCustomersAndOrders AS

                SELECT c.CustomerID,c.CompanyName,c.ContactName,c.Phone,o.OrderID,o.EmployeeID,
                o.OrderDate

                FROM Customers c,Orders o WHERE c.CustomerID=o.CustomerID

    而,ADONETDataView对象可以,筛选、排序、搜索DataTable的内容,但——它们并非SQL查询。

    不能用DataView在两个DataTable间联结Join数据。

    不能用DataView查看DataTable中的部分列。

    DataView确实支持基于动态标准的行筛选,但是,它们只能访问一个DataTable,而且,DataTable中所有列都可通过DataView得到。

    DataRelation来模拟连接

    可以用DataRelation配合一个基于表达式的列模拟联结。

    比如说:有一个客户DataTable和一个订单DataTable,可以在两个表之间创建关系,然后在订单表中添加基于表达式的列(用来显示客户表的列):

    Ds.Relations.Add(“CustomersOrders”,ds.Tables(“Customers”).Columns(“CustomerID”),
    ds.Tables(“Orders”).Columns(“CustomerID”))

    Ds.Tables(“Orders”).Columns.Add(“CompanyName”,GetType(String),
    “Parent(CustomersOrders).CompanyName”)

    3          在代码中使用DataView对象

    DataView对象提供了与DataTable对象的Select方法类似的功能。

    3.1         创建DataView对象

    要使用DataView对象查看DataTable中数据,必须【将它与DataTable关联】。

    可以——使用DataViewTable属性;或者在DataView构造函数中——指定所要使用的DataTable

    Dim tbl as New DataTable(“TableName”)

    Dim vue as DataView

    Vue=new DataView()

    Vue.Table=tbl

    Vue=new DataView(tbl)

    注意:如果使用DataView属性Table来设置关联的DataTable时,一定要保证DataTableTableName不能是默认值(就是空字符串)。

    这个限制在使用DataView的构造函数是就没有。

    DataView的另一个构造函数,签名与DataTable.Select方法极为接近。

    在其中,需要设置(DataViewTableRowFilterSortRowStateFilter

    Dim tbl as New DataTable(“Customers”)

    Dim dvrs as DataViewRowState

    Dvrs=DataViewRowState.ModifiedOriginal or DataViewRowState.Deleted

    Dim vue as newDataView()

    Vue.Table=tbl

    Vue.RowFilter=”Country=’USA’”

    Vue.Sort=”City DESC”

    Vue.RowStateFile=dvrs

    Vue=new DataView(tbl,”Country=’USA’”,”City DESC”, dvrs)

    3.2         使用RowStateFilter属性

    RowStateFilter属性接受DataViewRowState枚举类型值。

    RowStateFilter属性,能起到双重筛选程序的作用。比如:值ModifiedOriginal,表示修改过的行,会显示原始值。

    DataViewRowState枚举值表

    说明

    Added

    包括新添加的行

    CurrentRows

    包括未删除的行(这是默认值)

    Deleted

    包括被删除的行。

    ModifiedCurrent

    包括被修改的行,且显示“当前值”

    modifiedOriginal

    包括被修改的行,且显示“原始值”

    None

    不包括任何行

    OriginalRows

    所有的行(被删除的、被修改的、未被删除的),都显示“原始值”

    Unchanged

    包括未被修改的行

    3.3         使用DataRowView对象

    在使用DataTable.Select方法时,存在以下问题:如果指定了ModifiedOriginal,那么返回的是被修改过的行,对于返回的DataRow对象,需要调用过程才能得到行的原始值。

    因为DataView对象返回数据使用的是专门的“DataRowView对象”。

    DataRowView提供了与DataRow类似的功能,它公开了默认的Item属性,使用该属性,通过提供列名或者列索引来访问列的内容。DataRowViewItem属性,可以用来检查和修改行的内容;但是,“通过DataRowView只能使用一个版本的行数据”,也就是说,在DataView对象的DataRowVersion属性中指定哪个版本的数据,DataRowView就只能显示这个版本数据。

    Dim tbl As New DataTable(“Customers”)

    ...

    Dim vue As DataView

    Vue=New DataView(tbl)

    Dim row as DataRowView=vue(0)

    Console.WriteLine(vue(“CompanyName”)

    如果发现DataRowView对象的功能不足以满足要求,可以使用DataRowViewRow属性访问相应的DataRow对象。

    3.4         通过DataView检查所有可用数据各行

    DataView访问数据与直接访问DataTable数据略有不同。

    DataTable通过Row属性公开了自己的数据行(你可以用For Each遍历内容);

    DataView则没有此种可枚举的集合来公开数据。

    DataView对象公开了一个Count属性,该属性返回DataView可见行的数量。通过它可以构造一个For循环检查各行。

    DataView还公开了一个返回IEnumerator对象的方法(GetEnumerator)。IEnumerator对象属于System.Collections命名空间,提供了与DataReaderMoveNext方法类似的导航功能。

    Dim tbl as New DataTable(“Customers”)

    ...

    Dim vue as DataView

    Vue=New DataView(tbl,””,””,DataViewRowState.ModifiedOriginal)

    Dim rowView as DataRowView

     

    Dim intCounter as Integer

    For intCounter=0 to vue.count-1

         RowView=vue(intCounter)

         Console.WriteLine(rowView(“CompanyName”))

    Next intcounter

     

    Dim objEnum as IEnumerator=vue.GetEnumerator()

    Do While objEnum.MoveNext()

         Row=Ctype(objEnum.Current,DataRowView)

         Console.WriteLine(row(“Companyname”))

    Loop

    3.5         DataView中搜索数据

    DataView对象使用:RowFilterRowStateFilter——支持“筛选”。

    它还使用:FindFindRows方法——支持“搜索”。

    3.5.1   Find方法

    使用Find方法,首先要设置DataViewSort属性。Find方法根据Sort属性中指定的列来查找,可以 提供一个或多个值。

    不过,DataViewFind方法的返回值:不是DataRow或者DataRowView对象;它返回一个整数值,对应所需行在DataView中的索引。如果没找到,返回值为-1

    Dim strConn As String =”Providor=SQLOLEDB;Data Source=...;Initial Catalog=Northwind;
    Trusted_Connection=Yes;”

    Dim strSql As String=”Select ComstomerID,CompanyName,ContactName,Phone,City,Country
    from Customers”

    Dim da As New OleDBDataAdapter(strSql,strConn)

    Dim tbl As new DataTable()

    Da.Fill(tbl,”Customers”)

     

    Dim vue as New DataView(tb)

    Vue.Sort=“ContactName”

    Dim i As Integer=vue.Find(“Fran Wilson”)

    If i=-1 Then

        Console.WriteLine(“Row Not Found”)

    Else

        Console.WriteLine(vue(i)(“CompanyName”))

    End IF

    3.5.2   FindRows方法

    DataRowCollection对象中,其Find方法会根据DataTable对象的“PrimaryKey属性”,进行搜索,因为(主键也与惟一键约束相关联),所以最多只能有一行满足
    DataRowCollection.Find
    方法所指定的条件。

    然而,DataView对象的Find方法是根据(其Sort属性中指定的列)来进行搜索,DataView中的数据在此排序列可能有多行数据是相同值,此时不能用DataView.Find定位所有的【相同值数据行】,因为Find方法返回值是一个整数。

    DataView对象的另一个方法【FindRows】可以完成这种功能,调用方法跟Find一样,但它返回满足条件的DataRowView对象数组。

    ...

    Dim vue As New DataView(tbl)

    Vue.Sort=”Country”

    Dim arows as DataRowView()=vue.FindRows(“Spain”)

    If arows.Length=0 Then

        Console.WriteLine(“没找到”)

    Else

        Dim row As DataRowView

        For Each row in arows

               Console.WriteLine(row(“City”))

        Next Row

    End If

    3.6         修改DataRowView对象

    DataRowView对象修改一行数据,类似于修改DataRow的内容。

    DataRowView对象也公开了BeginEditEndEditCancelEditDelete方法。

    创建新数据行时,DataRowViewDataRow有点不同:

    DataView有一个AddNew方法,它返回一个新DataRowView,在返回的DataRowView调用EndEdit方法之后,新行才真正被添加到底层的DataTable

    Dim tbl as New DataTable(“Customers”)

    ...

    Dim vue as New DataView(tbl)

    Dim row as DataRowView=vue.AddNew()

    Row(“CustomerID”)=”ABCDE”

    Row(“CompanyName”)=”New Company”

    Row(“ContactName”)=”New Contact”

    Row(“Phone”)=”(617) 555-1212”)

    Row.EndEdit()

    修改一行

    Row.BeginEdit()

    Row(“CompanyName”)=”Modified”

    Row.EndEdit()

    删除一行

    Row.Delete()

     

  • 相关阅读:
    ios UIWebView截获html并修改便签内容(转载)
    IOS获取系统时间 NSDate
    ios 把毫秒值转换成日期 NSDate
    iOS  如何判断当前网络连接状态  网络是否正常  网络是否可用
    IOS开发 xcode报错之has been modified since the precompiled header was built
    iOS系统下 的手机屏幕尺寸 分辨率 及系统版本 总结
    iOS 切图使用 分辨率 使用 相关总结
    整合最优雅SSM框架:SpringMVC + Spring + MyBatis 基础
    Java面试之PO,VO,TO,QO,BO
    Notes模板说明
  • 原文地址:https://www.cnblogs.com/lizunicon/p/1344631.html
Copyright © 2011-2022 走看看