xBlues

My simple life in Shanghai

讨论用LINQ如何查重以及用纵横表显示数据

 

问题和要求如下:

 

 有数据表如下:

ID Owner Resource OrderID Quotation
1 Jack China 363 45
2 Jack China 363 45
3 Mike Japan 678 23
4 Mike Japan 678 23
5 Mike Japan 678 23
6 John China 893 12
7 John Korea 453 11
8 Mike China 234 78
9 Jack China 676 33
10 Mike Japan 454 25

首先根据查重Owner, Resource, OrderID, Quotation,去掉重复订单(但是需要保留其中任意一个ID号)

ID Owner Resource OrderID Quotation
1 Jack China 363 45
3 Mike Japan 678 23
6 John China 893 12
7 John Korea 453 11
8 Mike China 234 78
9 Jack China 676 33
10 Mike Japan 454 25

 

然后用二重分组Owner, Resource,来分组统计Quotation合计数量。用纵横表显示结果,左边第一行是人名,顶部行显示来源。

  China Korea Japan
Jack 78 0 0
John 12 11 0
Mike 78 0 48

 

这个问题折磨了我好几天还是没有解决,我下面的解决方法属于变通的方法,欢迎大家批评指正,也请高手发表你的改进方法。

 

查重,Linq使用Distinct方法,但是这个Distinct方法实际上不支持任何参数。

 

var result = (from r in SampleTable

select new { r.Owner, r.Resource, r.OrderID, r.Quotation}

).Distinct().ToList();

 

这样得到了出去重复订单的记录集,可是并不符合题目要求,因为题目要求保留重复记录的任意一个ID。

所以再用一遍Linq的join功能,的Join功能把ID按条件匹配出来。这样我就用了两步,不知道有没有方法可以一步完成。

 

具体写法,等我再看看。到目前为止其实是为了完成第二个要求做了准备工作,查重了。

我开始使用嵌套group by写了一个linq语句,

 

var result2 = from s in reslut

group s by s.Owner into groupA

select new {

Name = groupA.Key,

NewData = from t in groupA

group t by t.Resource into groupB

select new {

Resource = groupB.Key

Amount = groupB.Quatation.Sum()}

}


通过两个group by 的嵌套生成了一个嵌套结构的数据集,可以采用主总表的方式显示到页面。


具体方法可以采用两个ListView 嵌套,在外层的ListView的datasource里指定为result2,

增加一个数据绑定的时候变化内层ListView的数据源的事件,微软的帮助也是这样写的,原理上可以实现,但是已经看得我头大了!

 

又google了一下,发现原来我不需要用这个嵌套Group by的,其实我先用一个group by,查询出来一个数据集,使用ListView显示,然后再外层ListView里面定义一个Group By,就等于把内嵌的group by写到了前端界面控件里了,这样内嵌的ListView会自然切换数据集。这个方法看似简单。缺点是,使用了前端空间完成了嵌套逻辑。具体可以参考,Matt Berseth的博客文章,

http://mattberseth.com/blog/2008/01/building_a_grouping_grid_with.html

 

问题又来了,我的要求是纵横表,可是这样一天套等于一个纵表内,嵌套的表还是纵向排列的。找了好多资料都不得其解。

记得原来,我用SQL语句只要用多个字段group by一下,就可以了,现在使用linq却要嵌套group by才行!

而且查询出来的嵌套结构的结构显示起来极其不方便,简直是太难了。

 

原来用SQL我可以这样写:

select Owner, Resource, Sum(Quotation) from Table

groupby Owner, Resource

 

查询出来的结果我可以直接显示,因为不是嵌套结构。

即使是嵌套结构的查询结果,按着传统的ASP方法,或者新的MVC方法,我都可以直接用<%=%>输出,现在表单方式的ASP.NET我却必须要找一个页面控件,太复杂了。

 

不行,接着找,看看Linq是不是可以支持多列groupby。终于找到了这个澳大利亚人的博客,

http://ddkonline.blogspot.com/2008/04/linq-group-by-syntax-for-grouping-on.html

可以这样写,

var result3 = from c in Table

group c by new {c.Owner, c.Resource} into groupC

select new {

Name = groupC.Key.Owner,

Country = groupC.Key.Resource

Amount = groupC.Count()

}

 

结果显示出来的还不是纵横表,但是方法比较简单。

有高手看了,发表一下你的意见,看看我是不是没走对方向?


Tag标签: linq

posted on 2008-08-21 16:53 Blues 阅读(1278) 评论(4)  编辑 收藏 网摘

Feedback

#1楼  2008-08-21 18:12 路过而已路过而已 [未注册用户]

你要求显示的纵横表的列来源于resource这个列的动态数据数量..而LINQ表现列用的是属性...除非你能在C#里面动态增加属性...否则只有使用其他的变通方法...

比如按对象group by得出来的结果你再进行处理,拼接表,或者把中间resource列的数据用,分隔...显示的时候再进行处理   回复  引用    

#2楼  2008-08-21 20:55 Ivony...      

var result =
from dataItem in data
group dataItem by dataItem.OrderID into groupItem
select groupItem.First() into distinctItem
group distinctItem by distinctItem.Owner into ownerGroupItem
select
new
{
Owner = ownerGroupItem.Key,
Data = (
from resourceItem in ownerGroupItem
group resourceItem by resourceItem.Resource into resourceGroupItem
select new KeyValuePair<string, int>( resourceGroupItem.Key, resourceGroupItem.Sum( dataItem => dataItem.Quotation ) )
).ToDictionary( pair => pair.Key, pair => pair.Value )
};


试一下。   回复  引用  查看    

#3楼  2008-08-21 21:01 Ivony...      

嗯,测试通过了。   回复  引用  查看    

#4楼  2008-08-21 21:02 Ivony...      

当然还可以将所有地区都取出来然后做个Join这样更好,但意义不大。   回复  引用  查看    



标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
Google站内搜索

China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
近千种 9-95 新二手计算图书火热销售中!
开发者征途系统新作:《设计模式——基于C#的工程化实现及扩展》



相关文章:


相关搜索:
linq

相关链接: