数据源绑定杂谈

来源:互联网 发布:php调试技术手册 编辑:程序博客网 时间:2024/06/05 20:27

 

在开发应用程序的,包括web应用程序和windows应用程序的时候,经常会使用到数据源绑定操作。即从数据库表中取出数据放在DataTable或集合中,然后绑定显示控件上。这有时让人感觉很不可思议!它是怎么完成的?显示控件是怎么知道给它的是一个关系型的数据表或者集合,它的行和列从哪里来,特别是绑定后列名它是怎么得知的?为什么可以给DataSource赋一个数组类型、DataTableDataViewDataSetDataViewManager、实现IListSource接口的组件、实现IList接口的组件、泛型集合类或派生于泛型集合类的对象等等?

带着这几个问题,我们从以下面这个有趣的程序来慢慢揭开它神秘的面纱。

新建一个winform应用程序,在窗体中拖放一个DataGridView控件,并编写后台代码如下:

private void Form1_Load(object sender, EventArgs e)

       {

           //定义一字符串数组变量

           string[] strs = new string[]{"one","two","three"};

           //直接把数据源绑定到数组上

           dataGridView1.DataSource = strs;

       }

运行结果如下:

发现数据源绑定的不是字符串,而是相应字符串的长度。为什么?因为在把数组绑定到DataGridView控件时,控件会查找数组中对象的第一个公共属性,并显示相应的值。上面示例中显示的是字符串的长度,说明字符串对象提供的第一个公共属性是Length。故可以推测是否所有的数据绑定控件都是先识别绑定对象的成员属性,然后把属性名当列名。值则放到行中去显示。如果真是这样的话,下面这个示例就成立:通过上传控件上传图片,并通过DataList控件显示到页面上,如下图:

上图必须是显示图片,然后在图片下面写图片的名称。

代码如下:

       string upFolder = MapPath("~/UploadImages/");

       DirectoryInfo dir = new DirectoryInfo(upFolder);

        //获取目录中的FileInfo数组,然后绑定到DataList列表中

       dlstImages.DataSource = dir.GetFiles();//FileInfo[]数组

       dlstImages.DataBind();

DataList绑定代码如下:

   <asp:DataList

       ID="dlstImages"

       repeatcolumns="3"

       runat="server">

       <ItemTemplate>

       <asp:Image ID="Image1"

            ImageUrl='<%#Eval("Name","~/UploadImages/{0}")%>'

            style="width:200px"

            runat="server" />

       <br />

       <%#Eval("Name") %>

       </ItemTemplate>

       </asp:DataList>

可以从上述代码中发现,绑定图片地址是通过Eval("Name","~/UploadImages/{0}")进行的。而其中的Name 正式FileInfo对象的属性,也可以使用FileInfo其他属性,如CreationTime

如何解决示例1种只显示长度不显示字符串的问题,有上面两个例子可知,可以把字符串数组进行再封装。如下:

    Privateclass Cstring

    {

       private string _str;

       public string Str

       {

           get { return _str; }

       }

       public Cstring(string str)

       {

           _str = str;

       }

}

调试代码如下:

           //定义一个Cstring

           Cstring one = new Cstring("one");

           Cstring two = new Cstring("two");

           Cstring three = new Cstring("three");

           Cstring four = new Cstring("four");

           Cstring[] strs = new Cstring[] { one,two,three,four};

           //直接把数据源绑定到数组上

           dataGridView1.DataSource = strs;

结果:

按照上述分析结合Linq的实现,不难发现其实是用Linq获取数据并绑定到显示控件,跟上述第一个实例很像。不管Linq是手工创建实体,还是是用ORD创建,最终都是以类和属性(通过类名表示表名,属性名表示列名)的代码存在,跟上面字符串封装类很象。然后在把这些类与泛型,如IList<类名>IEnumerable<类名>,一起使用,然后最终绑定到显示控件上。或者是通过ObjectDataSource控件实现与显示控件的绑定。

对于ObjectDataSource对象,简单介绍下引用下书上的内容:“ObjectDataSource控件可以用来表示任何对象(任何派生自System.Object基类的派生类)。如果对象不支持IEnumerable接口,ObjectDataSource控件会自动地把该对象包装到一个支持IEnumerable接口的新对象。”通过了解,是否ObjectDataSource的包装行为也是和上面的字符串包装一样,并实现了IEnumerable接口。

在使用LinqObjectDataSource时,可以把LINQ查询封装到一个单独的类中,并使用ObjectDataSource来表示该类。当然也可使使用LinqDataSourceSqlDataSource控件,但是大多时候他们只能用在原型或实例,对于产品级应用还是建议使用ObjectDataSource。下面是其基本用法:

<asp:ObjectDataSource

 id="srcMovies"

//类名,可以是由Linq的实体类

TypeName="Movie"

//类提供的方法,返回值得实现了IEnumberable接口,可以是Linq实体类的扩展方法

SelectMethod="SelectByBoxOfficeTotals"

    runat="server" />

 

原创粉丝点击