`

ASP.NET服务器控件

阅读更多

 

6.数据源控件

 

ASP.NET具有强大的数据绑定功能。所谓数据绑定是指数据与控件相互结合的方式。可以绑定到属性,集合,表达式或方

法。大多数服务器控件都提供了对数据绑定的支持。单值绑定允许为控件的某个属性绑定一个变量,表达式或一个函数

。如果绑定后置代码里的变量或函数,必须指定其访问级别为public或protected(包括后面的<%= %>原因:http://kendezhu.iteye.com/admin/blogs/788770)。

语法是<%# %>

如给label的text属性绑定当前时间<asp:Label ID="Label1" runat="server" Text='<#DateTime.Now.ToString()%>'>  这里的绑定没有绑定后置代码里的成员

这时运行页面时没有效果的,要在后置代码中调用Page.DataBind()(根据http://www.cnblogs.com/KingStar/archive/2009/11/11/1600768.html页面生命周期来看,如果没有在控件事件里改变绑定值,放在Page_Load()里即可,在控件事件改变了绑定值的话还是将其放在控件事件里),该方法将对页面上所有的绑定表达式进行计算,也可以用Label1.DataBind()来计算特定控件的绑定表达式,<%# %>语法必须要有*.DataBind()才能绑定,也可以直接放在在页面上而不与控件结合。另外(<%= %>同样可以起到类似绑定后置代码里成员的效果,但其不能与控件结合,不能绑定到控件的属性,只能直接放在页面上)。还可以绑定后置属性,如显示当前网页文件的物理路径:<asp:Label ID="Label1" runat="server" Text='<%#Path%>'>,Path为字符串字段path的属性

        private string path = null;

        public string Path

        {

            get { return path; }

            set { path = value; }

        }

        protected void Page_Load(object sender, EventArgs e)

        {

            path = Server.MapPath(Request.Url.LocalPath);

            Page.DataBind();

        }

 

除了单值绑定,ASP.NET还有许多列表控件ListBox,DropDownList,CheckBoxList,RadioButtonList(只能显示一个字段(指向数据集的话)或属性(指向集合类的话))及功能更强大的GridView,DetealsView和FormView控件(能显示所有字段(指向数据集的话)或属性(指向集合类的话))支持重复值绑定。它们所共有的属性有:DataSource(指向数据集合,除DataReader,DataSet,DataTable等数据集以外,还可以是任何实现了ICollection接口的集合类如ArryList和泛型集合类List等)DataSourceID(数据源控件的ID)DataTextField(显示的字段(指向数据集的话)或属性(指向集合类的话))DataTextFormatString(显示的格式)DataValueField(值,对与列表控件可以用SelectedValue属性来获得相应的值)。下面就用DropDownList和RadioButtonList来演示绑定到集合类:

public class people

    {

        //给people类定义了3个属性

        public string Name{get;set;}

        public int Age{get;set;}

        public string Tel { get; set; }

        public people(string name,int age,string tel)

        { Name = name; Age = age; Tel = tel; }

    }

使用List集合类要引入using System.Collections.Generic;

public List<people> Getpeople()

        {

           //Getpeople方法用于初始化people类,并将people实例装进List泛型集合类里,然后返回这个集合类作为数据源

        List<people> Lists = new List<people> { new people("李四", 27, 13292828272),new people("王

五",26,15973648274),new people("张三",25,15083726453) };

            return Lists;

        }

  protected void Page_Load(object sender, EventArgs e)

        {

            if(!Page.IsPostBack)

          {

            //对DropDownList和RadioButtonList的属性进行设置

            List<people> Lists = Getpeople();  //获得数据源

            DropDownList1.DataSource = Lists;

            DropDownList1.DataTextField = "Name";  //只能绑定一个属性

            DropDownList1.DataTextFormatString = "人名:{0}";  //格式

            DropDownList1.DataValueField = "Tel";  //值是哪个属性的值

            RadioButtonList1.DataSource = Lists;

            RadioButtonList1.DataTextField = "Name";

            RadioButtonList1.DataTextFormatString = "名字:{0}";

            RadioButtonList1.DataValueField = "Tel";

            Page.DataBind();

          }

        }

 

在开发ASP.NET应用程序时,可以直接使用ADO.NET访问数据库,获得数据源并绑定到ASP.NET服务器控件中,

这个过程需要开发人员编写大量的代码,ASP.NET2.0后提供了一些列的数据源控件,使这些过程大大简化了

。大多数服务器控件都具有DataSourceID属性,使用该属性指定一个数据源控件便建立了数据源与控件之

间的关联。在学习这些数据源控件之前,我们还必须了解一下数据绑定的页面生存周期。数据源控件能完

成两大关键任务(向连接控制提供数据源数据和为数据源更新在控件中所做的更改)。周期如下:(1)创建

Page对象(2)开始页面生命周期,Page.Init和Page.Load事件触发(3)所有控件事件触发(4)如果数据源控件

中有任何更新,则完成更新数据库行为(5)Page.PreRender事件触发(6)数据源控件完成查询,并将查询数据

发送到相连接的控件中。(7)页面输出完成并释放。

每当页面PostBack都会执行这个过程,所以每次数据源控件都会查询一次数据库,造成一定性能开支,可以

在内存中缓存数据以便重用。

 

ASP.NET3.5包含的数据源控件有:

1.SqlDataSource

该控件在前面的ASP.NET控件中多次使用,它是调用ADO.NET里的类来访问数据库,从而获取数据和更新数据

。使用SqlDataSource可以访问(SQLServer,SQLExpress,Access,Oracle,DB2,MySQL等数据源,只要这些数

据源具有ADO.NET的提供程序)。下面我们来分析一下使用SqlDataSource数据源控件时每步操作产生的代

码:有一步是将连接字符串放到web.config中,除了便于集中管理外,web.config有安全的加密性。再下一

步可以使用自定义的sql语句或存储过程来从数据库检索数据,更多是使用指定表或视图的方式来从数据库

检索数据。如果选择了值返回一行,意思是SQL语句将使用DISTINCT查询。ORDERBY就不说了。当配置完以

后(选择了生成增删改语句)代码如下:

   <asp:SqlDataSource ID="SqlDataSource1" runat="server" 

       ConnectionString="<%$ ConnectionStrings:newsystemConnectionString %>" 

       SelectCommand="SELECT [id], [content], [newsid] FROM [comment]" 

       InsertCommand="INSERT INTO [comment] ([content], [newsid]) VALUES (@content,@newsid)" 

       DeleteCommand="DELETE FROM [comment] WHERE [id] = @id" 

       UpdateCommand="UPDATE [comment] SET [content] = @content, [newsid] = @newsid WHERE 

[id] = @id">

       <InsertParameters>

       <asp:Parameter Name="content" Type="String" />

       <asp:Parameter Name="newsid" Type="Int32" />

       </InsertParameters>

       <DeleteParameters>

       <asp:Parameter Name="id" Type="Int32" />

       </DeleteParameters>

       <UpdateParameters>

       <asp:Parameter Name="content" Type="String" />

       <asp:Parameter Name="newsid" Type="Int32" />

       <asp:Parameter Name="id" Type="Int32" />

       </UpdateParameters>

       </asp:SqlDataSource>

    重要属性有ConnectionString(指定连接字符串,还可以直接在其属性中指定连接字符串)另外还有一个属

性providerName(当使用SQLServer数据源时默认就是System.Data.SqlClient,但当使用其他数据源时就要

使用该属性了)***Command(指定执行的SQL语句)。

 

    在选择生成增删改语句时,还有一个是否使用开发式并发(就是对当多个人同时执行了相同的更新和删除操作的处理,选择了的话,执行SQL语句时会对每个参数进行检查,如果不符合查询要求,那么更新和删除操作将会失败。有俩属性ConflictDetection:冲突检测的方式CompareAllValues表示比较所有值,OldValuesParameterFormatString:表示在DeleteCommand和UpdateCommand中,where子句中原始数据字段的格式,后面要加{0})。选择后代码如下:     

      <asp:SqlDataSource ID="SqlDataSource1" runat="server" 

                ConflictDetection="CompareAllValues" 

                ConnectionString="<%$ ConnectionStrings:newsystemConnectionString %>" 

                DeleteCommand="DELETE FROM [comment] WHERE [id] = @original_id AND [content] = @original_content AND [newsid] = @original_newsid" 

                InsertCommand="INSERT INTO [comment] ([content], [newsid]) VALUES (@content, @newsid)" 

                OldValuesParameterFormatString="original_{0}" 

                SelectCommand="SELECT [id], [content], [newsid] FROM [comment]" 

                UpdateCommand="UPDATE [comment] SET [content] = @content, [newsid] = @newsid WHERE [id] = @original_id AND [content] = @original_content AND [newsid] = @original_newsid">

                <DeleteParameters>

                    <asp:Parameter Name="original_id" Type="Int32" />

                    <asp:Parameter Name="original_content" Type="String" />

                    <asp:Parameter Name="original_newsid" Type="Int32" />

                </DeleteParameters>

                <UpdateParameters>

                    <asp:Parameter Name="content" Type="String" />

                    <asp:Parameter Name="newsid" Type="Int32" />

                    <asp:Parameter Name="original_id" Type="Int32" />

                    <asp:Parameter Name="original_content" Type="String" />

                    <asp:Parameter Name="original_newsid" Type="Int32" />

                </UpdateParameters>

                <InsertParameters>

                    <asp:Parameter Name="content" Type="String" />

                    <asp:Parameter Name="newsid" Type="Int32" />

                </InsertParameters>

            </asp:SqlDataSource>

 

在讲GridView和DetealsView时都讲过主从表的效果,这其实就是对参数的过滤,只不过参数的值是从

GridView或DetealsView的selectedValue(在GridView或DetealsView中就是指选择的行的主键的值)中获

得。当然也可以从其他控件的某个属性获得,如DropDownList的selectedValue(在DropDownList中指选择的项的值)

当在where子句中添加了参数过滤后,SelectCommand="SELECT [id], [content], [newsid] FROM 

[comment] WHERE ([newsid] = @newsid)",SelectCommand属性就在后面加了过滤条件,我们在去看看这个

值是从哪得到的:<SelectParameters>

                    <asp:ControlParameter ControlID="DropDownList2" Name="newsid" 

                        PropertyName="SelectedValue" Type="Int32" />

                </SelectParameters>

是从DropDownList2的SelectedValue中得到的。你也许发现了,在选择源的时候有6种源(Contol(控

件),Cookie,Session,Form,QueryString(请求字符串),Profile),可以为它们的值设置默认值在

DefaultValue里设置。这6种源对应到代码里就是6种参数ControlParameter(其中PropertyName属性就是

指从指定控件的哪个属性中获得值,许多控件有自己的默认属性GridView或DetealsView的

selectedValue,DropDownList的selectedValue,CheckBox的Checked,FileUpload的FileBytes,Calendar的

SelectedDate,TreeView的SelectedValue等)FormParameter(Html窗体字段的值)

CookieParameter(不说了)SessionParameter(不说了)ProfileParameter(当前用户配置文件中的属性的值

,PropertyName属性指定配置文件的属性的名称)QueryStringParameter(不说了)。

 

SqlDataSource提供了很多事件供编程时调用Selecting(查询之前触发)Selected(查询之后触发)

Inserting,Inserted,Updating,Updated,Deleting,Deleted。在前面你看到的SelectCommand,

InsertCommand,DeleteCommand,UpdateCommand这四个属性,其实就是一个DbCommand类型(抽象类,SqlCommand和OracleCommand都继承于它,有许多此种类共有的属性如commandtext,commandtype,

Parameters,cancel等)的命令对象,所以SelectCommand="SELECT [id], [content], [newsid] FROM 

[comment] WHERE ([newsid] = @newsid)"

就相当于sqlcommand cmd=new sqlcommand();cmd.commandtext="SELECT [id], [content], [newsid] FROM [comment] WHERE ([newsid] = 

@newsid)";cmd.sqlconection="....";cmd.commandtype=commandtype.text;然后是执行;

而在这些Sqldatasource事件中有一个SqlDataSource***EventArgs类型的参数,该参数的Command属性(e.command)可以得到一个触发该事件的命令对象(这时的@newsid参数已经有值了),这时你就能任意的操作命令对象所有的属性(commandtext等,也就是说在这里你可以重新定义sql语句等)了。而e.Command.Parameters就是获得当前命令对象的sql语句中的参数集合(相当于cmd.Parameters),在这里自然是@newsid这一个了。同样可以添加,修改参数。当然作为任何集合我们都有遍历它的方法。如果一条语句有多个参数可以e.Command.Parameters[x].Value来获得某个参数的值,实例中经常用来获得一个参数值,然后看该值是否满足某种条件,如果不满足可用e.Cancel=true来取消这条语

句。对于那些ing的事件是可以获得更新前的参数值,而对于ed的事件的e.Command表示获得执行完SQL语句后的命令

对象。

此外SqlDataSource还提供了Select,Insert,Delete,Update这四个方法,可以在任何事件里调用这些方法完成相应的

操作:

        protected void Button1_Click(object sender,EventArgs e)

         {

              SqlDataSource1.Update();

         }

 

 

2.ObjectDataSource控件:使用SqlDataSource控件操作非常简单,但有一个很大缺陷,SqlDataSource与UI层过于紧密

,造成以后维护和修改的困难。于是便出现了ObjectDataSource控件,该控件是绑定到业务逻辑层提供的数据上。操

作也非常简单,但主要还是要亲自编代码,感觉不如不用ObjectDataSource控件,直接使用ASP.NET三层的思想来做项

目。

 

3.LinqDataSource控件:.NET Framework3.5引入了功能强大的LINQ(语言集成查询)特性,该特性又可分为LINQ to 

Object,LINQ to SQL,LINQ to XML以及一些其他类型的LINQ to xx。LINQ to SQL在数据库的表和对象之间建立了一

个映射(对象就可以表示那个表了),开发人员对映射的对象进行操作,而不用关心底层的实现细节。LINQ可以使用C#

或VB.NET编写实体类的查询,这些操作将被映射为相应的底层SQL操作,用户完全不用担心异构数据源的差异(后面会

讨论该技术)。

LinqDataSource控件将从语言集成查询中获取数据源(从LINQ to SQL实体类(表的映射)中获得数据),当与数据库中

的数据进行交互时,不会将LinqDataSource直接连接到数据库,而是与表示数据库和表的LINQ to SQL实体类(可在O/R

设计器里创建)进行交互,而LinqDataSource与LINQ to SQL实体类的交互是通过一个LINQ to SQL类的DataContext类(数据源实体上下文对象)实现的。DataContext包含它们的交互的连接字符串和用以操作数据库数据的方法,那些对

数据库的增删改查的方法都是默认拥有的,也可以在O/R设计器中将存储过程创建为DataContext的一个方法,当然也

可以自己创建方法到DataContext类中。

新添加LINQ to SQL类后进入O/R设计器可视化创建DataContext,在服务器资源管理器中把要被映射的表拖到右边栏

中形成表实体类,可以把存储过程或函数拖到左边栏从而形成DataContext的方法,右边的Name属性可以设置该

DataContext的名称。单击保存就自动生成代码了,同时也自动引入了System.Data.linq等相关命名空间,最后再重新

生成,至此,我们将数据库的实体类,表的实体类及这些实体类与LinqDataSource的连接管道DataContext都创建好了

。这时只要拖入LinqDataSource和数据绑定控件就可以完成效果了,LinqDataSource的使用与SqlDataSource的使用

大同小异。

最中生成的代码:

         <asp:LinqDataSource ID="LinqDataSource1" runat="server" 

            ContextTypeName="CommentDataContext" 

            Select="new (id, content, newsid)" TableName="comment">

         </asp:LinqDataSource>

ContextTypeName属性指定DataContext对象(该对象(映射到了)决定了可以对哪个数据库的哪些表进行操作)

TableName属性指定了对哪个表进行操作。

Select属性指定要查询字段的LINQ投影表达式(以后会讲)。

值得一提的是也可以在配置LinqDataSource时通过高级来启动增删改功能,但必须满足一下条件才能实现增删改功能

:(1)不能给Select属性赋值(2)不能给GroupBy属性赋值(3)ContextTypeName属性的值必须派生自DataContext

(4)TableName属性的值必须派生自Table<(Of<TEntity>)>

在配置数据源时你会发现当为select设置非*时,高级是不可用的。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics