LINQ to SQL 第九节 在控件中使用自定义的LINQ表达式(翻译自scott的博客)

光看别人写的不行,总得自己写点啥;要是实在没啥好的想法,就干脆翻译别人的。
看见博客堂中有人翻译Scott's Blog,最新是2007-08-07的,咋就不更新了呢?
闲话少说,咱来看看Scott 最近的随笔都写了些啥。
ps:这是小弟第一次练习翻译,那里翻的有问题望指正,谢谢!

LINQ to SQL 第九节  在<asp:LinqDatasource>控件中使用自定义的LINQ表达式
原文地址:http://weblogs.asp.net/scottgu/archive/2007/09/07/linq-to-sql-part-9-using-a-custom-linq-expression-with-the-lt-asp-linqdatasource-gt-control.aspx

最近几个星期我一直在写一系列介绍LINQ to SQL的博客随笔,LINQ to SQL是一个内建在.NET Framework 3.5发布版本中的O/RM(对象关系映射器),它能使你用.NET 类来模拟关系数据库结构。你可以使用LINQ表达式来查询数据库,以及更新,插入,删除数据。

以下是这个系列的前九节链接:


在这个系列的第五节中我介绍了新的.NET 3.5 数据源控件<asp:LinqDataSource>,并讨论了怎样利用该控件绑定ASP.NET UI控件和LINQ to SQL 数据模型。我也在接下来论述新的<asp:ListView>控件(第一节 - 利用简介的CSS创建一个产品列表页面)中示范了如何更进一步的使用它。

在这两篇文章中我所提及的问题相对比较简单(相关于单个表中的where子句),在今天的随笔中我将示范怎样在LinqDataSource控件中使用完整的Linq查询表达式,并show一下怎样使用任意的Linq to SQL查询表达式。

扼要重述:<asp:LinqDataSource>中使用声明性Where语句


在这两篇博客随笔中我示范了怎样用内建在LinqDataSource控件中的数据过滤功能来声明表达一个基于Linq to SQL数据模型的过滤语句。

例如,假设我们已经创建了一个NorthWind数据库的数据模型(创建方法我在这个系列的第二节中介绍过),接下来我们在页面上声明一个带有声明性Where过滤语句的<asp:LinDataSource>控件,让它只返回某个特定类别的商品信息(类别由一个查询字符串"categoryid"的值获得):


接下来我们把一个<asp:gridview>控件的数据源指向这个数据源控件并打开它的分页,编辑,和排序功能。

运行上面的页面我们得到一个基于产品数据的具有自动排序,分页,和编辑功能的GridView

使用上面例子中的声明性where变量可以处理大多数应用场景下的问题,但是,当产品的过滤条件变得很多而且复杂的时候问题就出现了,例如,如果我们只想根据一组动态可变的供应商来现实产品数据时我们该怎么做呢?

利用<asp:LinqDataSource>控件的Selecting 事件

你可以把自定义的查询场景挂接在<asp:LinqDataSource>控件的“Selecting”时间上,在这个事件中你可以添加任何代码来获取数据模型结果。你可以使用Linq to SQL查询表达式,或者一个存储过程,或者一个自定义的Sql语句来获取LINQ to SQL 数据模型。一旦你获取了一序列数据,你要做的只是把这个序列数据指定给LinqDataSourceSelectEventArgs对象的“Result”属性。<asp:LinqDataSource>控件讲使用这个序列数据来工作。

例如,下面是一个LINQ to SQL 查询表达式根据指定的一组供应商重新获取产品信息的例子。

注意:你不必把你的查询表达式写在这个事件的行中,一个更简介的做法是把查询表达式组装在一个方法中并在这个事件中调用,我已经在我随笔第八节的开始“show”了怎样创建这个方法(用一个GetProductsByCateGory方法)。

现在我们运行这个利用自定义Selecting事件句柄的页面,我们只得到了根据指定的国家数组作为供应商的产品信息。

上面最cool的事情是gridview的分页和排序功能依然工作的很好,虽然我们使用了一个自定义的Selecting事件来获取数据。分页和排序逻辑在数据库中发生意味着我们只从数据库中获取了10个产品,这些产品是根据GridView(指定供应商)的当前页来显示的。

你是不是觉得为什么我们使用了自定义的Selecting事件,但是分页和排序功能还能生效呢?原因是Linq使用了延迟执行的模式,那意味着查询并不是立即执行直到你尝试或者重获结果,延迟执行模式的其中一个好处是使你只拘泥于组成自己的查询逻辑而不关心其它的查询,你只需要附加自己的行为到上面即可,你可以在我Linq to Sql 第三节的博客随笔中学到更多内容。

在上面我们在Selecting时间句柄中声明了一个我们想执行的自定义Linq查询,并把它的结果指定给了"e.Reult"属性.我们仍然没有立即执行它(只要我们不尝试或者重获结果或者调用"ToArry(),ToList()"方法)。LinqDataSource所以能够自动的给查询增加一个Skip和Take方法,相当于增加了一个"order by"语句。所有这些值根据gridview的分页和排序信息被自动计算。直到LinqDataSource执行了Linq表达式并获取数据,Linq to sql将利用确信在数据库中的分页和排序逻辑,只返回需要的10行产品数据。

注意到下面我们仍然可以使用GridView的编辑和删除功能,虽然我们使用了自定义的LinqDataSource的"Selecting"事件

编辑和删除功能仍然工作的原因是我们Selecting事件中指定的查询结果序列是一个正规的实体对象(例如:产品类型序列,供应商类型,类别类型,订单类型等).LinqDataSource能够自动的在UI控件执行更新操作时挂接到上面。

要学习更多的关于Linq to Sq怎样进行更新工作,请参考这个序列的第四节,然后读这个序列的第五节看看LinqDataSource的Updates动作。

在Selecting时间中执行自定义的查询项目

Linq 最强大的公用之一是能自定义"形式"或者"项目"数据。当你只需要获取一个实体值的子集的时候你可以使用一个Linq to Sql 表达式来实现。并且/或者要在运行时根据自定义的表达式动态的计算新的值的时候。你可以学到更多关于怎样实现查询项目或者形式在本系列的第三节。

例如,我们改变我们的Selecting事件来在GridView上现实一组自定义的产品信息,在这个列表中我想现实产品id,产品名称,产品单价,这个产品的订单数量,以及这个产品由收件人付款的订单收入总和。我们能利用Linq表达式动态的计算最后两个值,例如下面这样:

注意:用在上面计算收入的的Sum方法是一个扩展方法的例子,这个方法使用了一个Lambada表达式的例子,它根据Linq查询表达式生成的结果类型是一个匿名类型,所以它的形式是根据查询表达式推断出来的。扩展方法,lambda 表达式,匿名类型都是VS2008中VB和C#的新的语言特性。

我们自定义Linq表达式的查询结果被绑定在Gridview上,如下:

注意到分页和排序功能仍然工作,虽然我们使用了自定义Linq 形式/项目结果数据。

不能和自定义形式/项目结果工作的功能是行内编辑,这是因为我们自定义了项目在Selecting时间中,导致LinqDatasource没办法准确的知道怎样更新一个未知的实体,如果我们想给自定义数据形式的gridview增加编辑功能,我们需要改换成Objectdatasource控件(这样我们可以提供一个自定义的更新方法挂接在它的更新行为上),或者使用户导航到另一个新页面来实现更新,该页面显示一个DatailsView 或者FormView控件绑定产品实体来编辑(并不在列表中尝试行内编辑)。

总结:

你可以很容易的使用内建在LinqDataSource中的声明性过滤支持来实现大多数场景下查询Linq to Sql数据模型的需要。

要实现更高级或者自定义的查询表达式,你可以利用LinqDataSource的Selecting事件,它使你实现任何获取和过滤Linq to Sql 数据的逻辑。你可以调用方法来获取数据,或者使用Linq 查询表达式,或者存储过程,或者调用一个自定义sql语句来实现。

希望本篇对你有所帮助。
Scott

转载于:https://www.cnblogs.com/xiaozhuang/archive/2007/09/12/891036.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值