LINQ下使用三层架构的探索(六)逻辑访问层中的数据统计以及一个主从报表。

以前,我们要在某个报表中显示统计信息一般有两种方法:1通过一个SQL查询——我们可以向数据库发出一个额外的查询来为某个特定的类别计算统计信息。SQL包含一系列的聚合函数,并由GROUP BY子句指定应该根据什么数据来进行统计。2在表示层中统计已经获取的信息,大家可以参考这个http://reeezak.cnblogs.com/archive/2006/07/09/446444.html

然而这两个方法都有他们的缺点:

第一种方法很明显,他增加了一次到数据库的往返,因为在获取报表信息的时候我们已经对数据库进行了一次访问,而我们要获得的统计信息可以从报表中获取。而且无法获取更加复杂的业务统计。

第二种方法则没有很好的让层次划分出来,我们更加希望表示层中仅仅使用方法而不要去设计这些方法。(尤其是一些业务规则,比如NBA中有“球员效率”这项数据,但如果不是很熟悉这项业务的程序员是不知道这个效率是如何计算的。)

既然我们使用了分层架构,就应该把这些职能分开,表示层的设计者只需要设计UI,了解方法的名称就可以了。具体的业务计算应该留下来给业务逻辑层的设计者去设计。

有了LINQ我们就可以把这些东西都放到业务层去了,因为数据操作已经对象化,在逻辑层中就可以方便地统计数据并且直接在表示层调用这样的方法。

按部就班的做

1我们需要一个下来列表来选择门类,所以我们需要一个门类列表,在Productbll中添加一个新的方法GetCategory代码如下:

[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, true)]

    
public IQueryable GetCategory()

    
{

        var category 
= from p in db.Categories

                      select p;

        
return category;

}

2代码很简单我就不解释了,由于我们的重点不是这个门类选择列表,所以我直接选择了全部字段,其实只要IDName两个字段就可以了。新建一个WEB窗体,添加一个下拉列表,在自动回送上打勾,选择新建数据源。

3数据源选择对象数据源,选择Productbll,方法选择GetCategory,点击完成。字段显示填写CategoryName,字段值填写CategoryID


4然后就是显示统计和从报表的方法,在GetCategory方法下添加一个新方法GetProductByCategoryID,代码如下:

[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, true)]

    
public IQueryable GetProductByCategoryID(int categoryID,out decimal? total)

    
{

        total 
= 0;

        var product 
= from p in db.Products

                      
where p.CategoryID == categoryID

                      select p;

        
foreach (Product p in product)

            total 
+= p.UnitPrice;

        
return product;

}


5简单的代码解释:

1)         这是一个包含2个输出的方法,方法本身是可以作为数据源的IQueryable类型,另外还会输出一个十进制类型数,也就是总价

2)         获取CategoryID与输入参数categoryID相匹配的记录

3)         遍历这些记录,获取他们的价格之和

4)         返回这些记录与总价

6在页面中添加一个GridView与一个Lable控件,双击下拉列表,进入事件,加入如下代码:

decimal? sum = 0;

        GridView1.DataSource
=product.GetProductByCategoryID(Convert.ToInt16(DropDownList1.SelectedValue),out sum);

        GridView1.DataBind();

        Label1.Text 
= "总价:"+Convert.ToString(sum);

7运行该页面,任意选择一个门类,观察总价和这些记录。

小结:
这章的内容并不多,需要注意的是我们使用了返回多个结果的方法,方法本身是IQueryable类型,另外还会输出一个十进制类型数,也就是总价。我们在逻辑层中查询结果,并且进行遍历,获得总价。在表示层中我们仅仅调用了方法,而且对数据库仅有一次操作。
比起直接用SQL获取总价来说,我们的方法少了一次数据库的往返。比起在表示层写方法,我们的方法的层次更加分明。在没有使用这样的结构以前,也可以在逻辑层这么做,只不过还需要手动的把数据转换成可以遍历的对象,而现在一切都方便了。可以直接对Product表中的记录使用for each。除此之外我们不需要做更多的工作。

posted @ 2008-04-05 17:42  NafLian  阅读(4713)  评论(17编辑  收藏  举报