xBlues

My simple life in Shanghai

2008年8月21日 #

讨论用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()

}

 

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

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


posted @ 2008-08-21 16:53 Blues 阅读(1617) 评论(4) 编辑

2008年8月1日 #

LINQ迸发访问错误提示:DataReader associated with this Command which must be closed first

摘要: 我有一个应用是采用LINQ生成的DBML写的,同时执行两种操作的时候出现迸发错误。 操作一:读表 操作二:写表(时间较长的操作,大约持续1分钟) 在web.config中增加下面的参数可以消除这种错误。 MultipleActiveResultSets=true" 我照这样做了,写表的同时,读表不出错了。可是写表的操作却开始一直报错,看来还是没有解决问题。还有一种解释,我注意到我的代码的写法,可能是这里出错了,为了不是每次表操作都去建立一个新的DBDataContext实例,我就统一建立了一个静态实力,看上面的说法,这样不行。看来需要给每一个操作定义一个单独的实例。 这样子不行: public static MyDBDataContext db = new myDBDataContext(); 那看来得每个操作页面定义一个对象实例,操作完成以后再关掉,你有什么好的办法么?阅读全文

posted @ 2008-08-01 16:38 Blues 阅读(1517) 评论(1) 编辑

2008年7月31日 #

如何在ASP.NET应用中集成Windows域帐户来进行权限控制

如何在ASP.NET应用中集成Windows域帐户来进行权限控制

 

企业应用程序采用域用户来代替独立的用户管理模块的好处很多。

  • 程序本身不需要单独编写用户帐号管理模块
  • 与域用户集成,用户不需要单独记忆用户名口令,可以实现无缝登录
  • 采用域用户方案安全性提升,认证时口令不在网上传输,域用户安全级别
  • 其他好处多多

首先需要配置IIS:

为你的应用单独建立一个web虚拟目录,右键选择属性里的目录安全,权限与访问控制,把“打开匿名访问”不选,仅仅选择“集成Windows权限认证”,别的都不要选,确定。

 

集成域用户来控制用户访问的途经有两种,一种是利用NTFS权限控制表,缺点是每次转移应用之后,需要逐个设置目录访问权限。另外一种是通过配置web.config文件,通过URL来控制,好处是直接修改配置文件就可以了,不需要每次发布应用时变换一次目录就修改一次。下面我就主要介绍一个后者。

 

划应用目录树:

根目录的权限设置覆盖子目录的设置,把管理页面单独放在一个路径下,比如在根目录下设置一个admin子目录管理页面都放在这下面;再设置一个sales的子目录,只有销售的同志可以访问,user则是任何人都可以访问。举例如下:

\root\

\root\admin

\root\sales

\root\user


 

修改配置文件:

在需要进行权限配置的目录下面,分别建立web.config文件。root下面肯定需要一个配置文件了,在本例中由于admin路径下放置了管理页面,因此我在admin下面也建立了一个web.config配置文件。

 

root下的web.config配置文件的和权限相关的内容如下:

<?xml version="1.0"?>
<configuration>
    
<connectionStrings>
        
<add name="APPConnectionString" connectionString="Data Source=MachineName;Initial Catalog=DatabaseName;Integrated Security=SSPI"
    </connectionStrings
>
    
<system.web>
        
<authentication mode="Windows" />
            
<!--<identity impersonate="true" userName="UserName" password="PassWord" />-->
            
<identity impersonate="true"/>
        
<authorization>
            
<allow roles="UserName,domainname\username1,domainname\username2,domainname\usergroup1" />
            
<deny users="*"/>
        
</authorization>
    
</system.web>
</configuration>

 

admin目录下也增加一个web.config文件 (sales目录下配置文件类似,就是允许sales的账户访问该目录即可)

<?xml version="1.0"?>
<configuration>
    
<system.web>
        
<authorization>
            
<allow roles="domainname\username1,domainname\usergroup1" />
            
<deny users="*"/>
        
</authorization>
    
</system.web>
</configuration>

 

首先,先解释一下admin下面的这个配置文件,我允许domainname\username1访问这个管理目录,而禁止任何其他的用户来访问这些功能页面。

下面,再接是一下root下面的这个配置文件,我增加了一个链接数据库的字符串,采用的是MS推荐的安全连接,没有使用sa之类的SQL管理的账户。

 

authentication mode="Windows" 的意思是集成域用户,这句话是打开应用支持域用户的关键。

allow roles=",,," 列表里面我规定了可以访问root的用户,每个用户之间用逗号分隔,这里可以指定服务器本机用户,也可以指定域用户,或者域用户组

deny users=",,," 列表里我规定了禁止所有用户访问(允许列表里的用户除外)

以上这两个类表可以使用的通配符有 ? 匿名用户, * 所有用户

 

到目前为止,其实就已经算是完成了,就这么简单。

 

用户代理

Impersonate,除非有特殊要求,比如在同一个服务器上运行同一个应用,需要区别不同公司的操作,可以分别建立应用程序池,采用不同代理帐号,来区分访问,否则,这个代理账户是不需要的(而且会引起性能下降),这个代理用户现象缺省是关闭的。

 

如果不采用用户代理,每次用户登录应用的时候,系统自动匹配当前用户登录所使用的客户端的域用户名

如果采用用户代理,就是指定一个代理用户,代理所有表现曾用户的一切操作请求。

 

可以用下面的配置指定固定的代理用户

<identity impersonate="true" userName="UserName" password="PassWord" /> 

或者采用下面的设置,指定应用程序池的用户作为代理

<identity impersonate="true" />

 

缺省情况下,这个用户代理是关闭的,缺点也不少,MS不推荐使用,所以,你就跳过这部分吧。

 

 

下面说一下如何采用信任账户去链接SQL数据库

这一部分,实际上用的很广泛,MSDN有专门的一篇来讲解这个,你可以参考,

http://msdn.microsoft.com/en-us/library/ms998292.aspx

 

如果使用了sa或者其他SQL管理的用户帐号,那实际上我就把口令写到了配置文件里面,这样安全性不好。当然微软也提供了补救办法,就是可以使用一个命令行加密工具把配置文件加密成密文,总之是不好了,那怎么使用信任连接连接数据库呢?配置文件照着下面写,

<connectionStrings>

    <add name="ConnectionStringName" connectionString="Data Source=ServerName;Initial Catalog=DatabaseName;Integrated Security=SSPI" providerName="System.Data.SqlClient" />
</connectionStrings>


下一步是怎么配置这个信任的用户的权限,这个账户必须同时具有运行IIS应用的权限,和访问SQL的权限。一般可以指定一个特定的新建用户,当然,为了简化配置,如果web服务器和SQL服务器都在一台机器上,也可以使用预置好的服务帐户NT AUTHORITY\NETWORK SERVICE,否则你就需要建立一个域用户了,格式可以是domainname\webmachinename。然后就是分配给这个用户访问SQL的权限。

 

 

给应用指定运行用户

建立一个新的应用程序池,右键选择属性,identity用户表示里面,把匿名用户去掉,在下面选择用户,可以选择你上面新建的用户,也可以使用NT AUTHORITY"NETWORK SERVICE。



在代码中调用域用户权限
 在代码使用如下代码来查看访问者域用户身份。

Page.User.Identity.Name

Page.User.Identity.IsAuthenticated


增加引用using System.Security.Principal;

 

使用如下代码查看采用信任链接 方式同一访问SQL的用户身份,也就是你在应用程序池里指定的那个用户名。

WindowsIdentity.GetCurrent().Name

 

如有错误,欢迎批评指正。

 

下面图标说明了应用层采用Windows用户进行安全认证,应用层和数据服务器之间则采用信任链接统一访问的原理。

 

 


posted @ 2008-07-31 12:03 Blues 阅读(2862) 评论(12) 编辑

2008年7月23日 #

如何使用ExtJs为表格单元格增加Tooltips(QuickTips)浮动信息

ExtJs证实了其十分强大的界面定制能力,其中的提供的ToolTips功能比HTML里的如下语句定制性更强,完全可以代替如下功能

<a href="http://dfdfd" title="TIPS">Some Text</a>

 

ExtJs是通过Ext.ToolTip和Ext.QuickTips两个组件来实现浮动提示功能的,其中Ext.ToolTip的定制功能很强,具体效果可以参考,具体配置代码如下,

ToolTip配置代码

 

但是Ext.ToolTip的缺点也是很明显的,他需要在配置中写入提示内容文本,这样如果想在表格中引用,给表格中的某一列增加浮动提示这种情况就很不方便,代码也会十分混乱。(当然有高手是可以通过函数解决这个问题的,请高手指点)。ExtJs2.0增加了一个扩展组件就是Ext.QuickTips实际上正好解决这个问题,支持在超文本中定义浮动提示的内容,这样用ASP.NET的数据绑定组件引用起来十分方便,界面也比HTML中的那个缺省的样式好看,唯一的缺点是QuickTips的定制没有ToolTip那么灵活,像上面展示的支持拖拽,鼠标点击关闭,AJAX都不好实现,但总比没有强。下面我就说说,这个QuickTips怎么具体配置,

 

首先在header里增加ExtJS的引用

<link rel="stylesheet" type="text/css" href="ext-2.1/resources/css/ext-all.css" />
<script type="text/javascript" src="ext-2.1/ext-base.js"> </script>
<script type="text/javascript" src="ext-2.1/ext-all.js"> </script>

 

然后再在header里对Ext.QuickTips配置

Ext.QuickTips.init(); 是必须的

Ext.apply(Ext.QuickTips.getQuickTip(),{...}); 是可选的,如果你想使用缺省配置,就完全可以省略掉这一段。

  • maxWidth 最大宽度
  • minWidth 最小宽度
  • showDelay 延时显示(毫秒)
  • trackMouse 随着鼠标移动
  • hideDelay 延时自动隐藏 (缺省为true)
  • closable 显示关闭图标(但是这个图标显然只是一个样子,鼠标点击不到它!)
  • autoHide 自动隐藏 (这个配置没用处,不管是真是假,都自动隐藏,实际需要用下面的dismissDelay来控制)
  • draggable 支持用鼠标拖动(实际上这个选项也不起作用,因为鼠标根本移动不到这里!)
  • dismissDelay 这个才是最有用的选项,否则你完全可以省掉这段Ext.apply的配置。因为缺省情况下这个浮动提示是经过一段时间以后就自动隐藏。只有通过设置这个值为0来关闭自动隐藏浮动提示!
<script type="text/javascript">
Ext.QuickTips.init();
Ext.apply(Ext.QuickTips.getQuickTip(), 
{
    
//maxWidth: 200,
    //minWidth: 100,
    //showDelay: 50,
    //trackMouse: true,
    //hideDelay: true,
  
    
//closable: true,
    //autoHide: false,
    //draggable: true,

    dismissDelay: 
0
}
);
</script>

 

 最后在body里增加对Ext.QuickTips的引用,qtitile可以视情况而定可以省掉而仅仅保留qtip,在qtip里增加绑定内容。

<input type="button" value="OK"
class
="tip-target" ext:qtitle="OK Button" ext:qtip="This is a quick tip from markup!">
</input> 

<asp:ListView  >

<ItemTemplate>
<div id="sample"
ext:qtitle
='<%# Eval("TipsTitleField") %>' ext:qtip='<%# Eval("TipsField") %>'>
<%Eval("SampleField"%>
</div>
</ItemTemplate>
</asp:ListView>

 

posted @ 2008-07-23 04:54 Blues 阅读(3907) 评论(4) 编辑

2008年7月11日 #

MSDN上发现了一篇很好的WCF入门教程

摘要: 看了园子里很多学习WCF的例子,感觉受益匪浅,但是由于每个人学习的侧重点不同,一些很详细的细节例如每一个属性都是用来干什么的,建立不同的项目类型对创建的服务有什么区别等等,都不得而知。终于,在MSDN上发现了一篇入门教程。讲解的十分基本,十分详细,想进到每一个细节,然我彻底了解入门的每一个细节,整个教程结构清晰,代码简洁,讲解细致,值得推荐。每一个细节都包含在两个Program.cs文件中了,你大概看一下就会懂。比院子里大多数教材说得都清晰,特别适合像我一样爱刨根问底的初学者。:)阅读全文

posted @ 2008-07-11 15:48 Blues 阅读(16827) 评论(18) 编辑

2008年7月7日 #

FileHelper 一个极好的数据文本文件处理类库

摘要: 我经常接触到一些csv格式存储的数据文件,把这些文件导入数据库,或者把数据库的数据导出成为excel文件或者csv文件。自己写功能解析自然好,但是需要处理的地方太多,如果是标准文件还好,但是如果文本文件里含有保留分隔符,或者数据格式有一些小错误,都需要自己处理。而且如果数据格式变化了,每次还要修改自己的代码。所以,我一直没写这个代码。偷懒,一直用Excel的Text to Data 功能凑合,或者用SQL的导入导出功能,再就是用从网页上拷贝粘贴数据到excel,然后清除格式的方法。这些方法其实都有弊端,典型的就是大量的手工才做,重复劳动,这些到还能忍受了,当涉及到数据库,用的最多的自然就是SQL自带的导入导出功能。这个功能大体上好用,可是如果文本文件里面有一点错误,他就罢工。这倒还可以忍受,后来我在64位机器上装了64位的SQL,这样微软居然不支持直接由Excel 导入,说64位版本不需要这个功能,我在网上看到了许多类似需求,微软都坚持说不提供这个64位的flat文件驱动!一等就是3年,SQL2005年发布,现在已经2008年了。可怕。终于看到了这个阿根廷人编写的开源文本文件导入导出帮阅读全文

posted @ 2008-07-07 14:41 Blues 阅读(4352) 评论(11) 编辑

2008年7月4日 #

好久没写了

摘要: 回来看看,一会接着写!阅读全文

posted @ 2008-07-04 17:06 Blues 阅读(53) 评论(0) 编辑

2006年7月11日 #

招聘 .net 程序员

摘要: 招聘 .net 程序员工作地点:上海工作性质:兼职(独立开发,但是为方便联系,人需要在上海,具体工作地点和时间不限)开发周期:1-2个月报酬总额:1万元人民币技术要求:有实际采用VS2005进行基于ASP.NET 2.0开发的经验,对分层结构有较深理解。项目要求:主要功能模块不复杂,重点是框架设计,程序采用分层设计,容易扩展功能,考虑项目今后扩展的要求,DAL层考虑基于ADO.NET 2.0类库的...阅读全文

posted @ 2006-07-11 17:13 Blues 阅读(1096) 评论(6) 编辑

2004年6月23日 #

American Top 40

摘要: American Top 40 with Ryan Seacrest以前总是犯愁怎么找到最流行的歌曲,去过了好多地方,都感觉不太好,偶尔在FM887听到了这个节目,感觉主持人那么专业,真的比887的主持人高出一截,而和英语主持人比较起来就更加专业了,我第一个感觉就是这一定是一个引进节目,没想到被我猜中了,这个可是当今美国最火的FM节目,而排行榜也绝对具有代表性,可惜离开了北京,无法收听这个节目了,...阅读全文

posted @ 2004-06-23 09:17 Blues 阅读(1534) 评论(0) 编辑

2004年6月21日 #

第一个帖子吧,我也博客了!

摘要: 嗯,早就打算编写自己的网络程序,不过,不急于动手,先看看时下流行的东西吧,写程序和买东西一样,我的套路是先转遍全市场,再作决定。阅读全文

posted @ 2004-06-21 09:10 Blues 阅读(112) 评论(0) 编辑