‘ASP.NET’ 分类下的所有文章
2016六月3

json转类

ASP.NET 评论关闭

将json转成class在线工具 http://json2csharp.com/

2015七月24

winform自动升级程序

ASP.NET 评论关闭

1,简单点,将程序放在共享中,从共享访问。缺点是在更新时需要程序都通出才能覆盖。
2,升级,用microsot提供的clickonce技术,自动更新,缺点是有限制
3,用通用组件 AutoUpdater.NET

2014十一月18

tfs提交保留.refresh文件,去掉.dll文件

ASP.NET 评论关闭

在bin下,若对其添加到TFS,则项目成员在生成时回相互签出,操作不便,而若掩蔽Bin文件,则.refresh文件则也被掩蔽,若添加新的引用,就不能让项目组其他成员获取。
解决方法,有TFS提供的掩蔽文件,指定哪些不添加进tfs,若dll
方法:
自动生成.tfignore文件

在 *** 挂起的更改 *** 页上,在 *** 排除的更改 *** 部分中,选择 *** 检测更改 *** 链接。

*** 提升候选更改 *** 出现对话框。

选择文件,打开其快捷菜单,并选择 *** 忽略此本地项目 ***、*** 通过扩展忽略 ***或 *** 由文件名忽略 ***。

选择 *** 好 *** 或 *** 取消 *** 关闭 *** 提升候选更改 *** 对话框。

.tfignore文件显示在 *** 挂起的更改 *** 页的 *** 包含的更改 *** 部分。 可以打开此文件并修改它以满足您的需要。

.tfignore文件自动添加为包含挂起的更改,以便您创建的规则将应用于获取文件的每个团队成员。

参考:向服务器添加文件 http://msdn.microsoft.com/library/vstudio/ms245454(v=vs.110).aspx#tfignore

2014十一月18

dll文件引用存储位置

ASP.NET 评论关闭

1,通过浏览添加的DLL,会在bin下面生成一对应人.refresh文件,里面有存位置
2,通过添加整个项目方式,会在.sln文件中保存此配置
3,通过添加.net已有程序集的方式,会在web.config中有记录。

Visual Studio Website Reference Paths

http://stackoverflow.com/questions/279451/visual-studio-website-reference-paths

2014五月17

session保存到远程服务器

ASP.NET 评论关闭

上ngix做负载均衡,ngix可以据IP固定一台服务器访问,这样可解决session共享问题,不过,还是单独一台服务器存session好一些,可以放到缓存或者服务中。

1,在web.config中配置:

<sessionState mode="StateServer" stateNetworkTimeout="10" timeout="120" stateConnectionString="tcpip=172.16.88.88:42424" >
</sessionState>

2,在指定服务器172.16.88.88中开启远程访问

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters:
AllowRemoteConnection=1
 
2014五月3

web发布与压缩

ASP.NET 评论关闭

vs2012已经提供了发布功能,可以直接ftp上传,但ftp上传是对每个文件上传,若网速比较慢,就时间比较长。这里提供命令行发布,然后进行压缩操作。

@echo off

set fdir=%WINDIR%\Microsoft.NET\Framework64

if not exist %fdir% (
set fdir=%WINDIR%\Microsoft.NET\Framework
)
set msbuild=%fdir%\v4.0.30319\msbuild.exe
%msbuild% website.publishproj /p:DeployOnBuild=true /p:PublishProfile=.\App_Data\PublishProfiles\发布.pubxml /p:VisualStudioVersion=11.0 /p:OutputPath=M:\deploy

rd /s /q M:\deploy\images
rd /s /q M:\deploy\Files
del M:\deploy\web.config
del M:\deploy\login.aspx
rename M:\deploy\login3.aspx login.aspx

"C:\Program Files\WinRAR\rar.exe"  a -ag -k -r -s -ibck M:\s6release\s6_.rar M:\deploy

start M:\s6release

其中,发布的两个文件website.publishproj与发布.pubxml,可以通过在网站上右键发布来生成,生成的文件分别在网站根目录与App_Data\PublishProfiles下。
winrar:

winrar.exe:运行winrar,
如果winrar.exe没在默认路径中则需要指明路径,如c:\Progra~1\winrar\winrar.exe …;
a :备份所有文件;
-ag :当创建压缩文件时,以格式“YYYYMMDDHHMMSS”附加当前日期字符串,文件名bakYYYYMMDDHHMMSS.rar;
-k :锁定压缩文件;
-r:备份目录和子目录;
-s :创建固实压缩文件;
-ibck :后台运行;

M:\s6release\s6_.rar :备份的路径和基本名称(-ag参数会自动在bak后加上系统当前时间),
也可不用-ag参数,通过“%date:~0,4%%date:~5,2%%date:~8,2%”取得时间字串,
也可写作c:\bak.zip;

M:\deploy :要备份的文件目录。

 

2014三月24

restful webapi

restful:表现层状态传输
1,返回的结果格式由客户端的Content-Type指定,即表现多变
2,对应的方法是get,post.GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。

3,mvc webapi对应:建立的方法由[[HttpPost]]指定关联

  

引用:理解RESTful架构  ASP.NET Web API(一):使用初探,GET和POST数据

控制ASP.NET Web API 调用频率
ASP.NET Web API 接口执行时间监控

可以用chrome提供的插件来进行构造测试
 Postman – REST Client

2014二月26

D3.js

ASP.NET 评论关闭

大数据下的可视化工具,绝对强大,可以动态展示很多数据,图形不固定,图形可以是矢量的

https://github.com/mbostock/d3/wiki/Gallery

2013九月20

vs2012 fake功能

ASP.NET 评论关闭

    在测试过程中,被测试的功能并不总是很简单,可能这个功能块有多个逻辑组成,如其中一个逻辑A是要查询数据库返回一个列表,那么在编写测试方法时就不得不考虑连接数据库的事情,并且,若数据库发生更改的话,做的测试也需要相应的更改。此时利用fake来假冒逻辑A即可,即是将逻辑A查询数据库的方法做一委托,用自定义的代码返回值即可,这就实现了与数据库的无关性。

Stub:接口模拟
Shim:具体方法模拟
在测试时
1要引入 Microsoft.QualityTools.Testing.Fakes;
2,要在模拟上下文中操作,只有这样类用到有模拟的方法才会自动调用我们所实现的
using (ShimsContext.Create())

 

Microsoft Fakes 可以提供成员模拟的方法.以方便进行单元测试

如果不使用模拟方法我们要关心很多东西,如数据库的数据变化,接口调用导致的变化,文件、及其它资源的访问等问题。

使用模拟我们则可以只关系我们需要测试的那部分逻辑。

clip_image001

一 、Stub 和 Shim

Microsoft Fakes 提供了两种模拟类型成员的方式.以下两种方式的替代实现,都可以由委托来重新实现.

1.Stub Type,存根类型,可以动态地为接口及非密封的virtual或属性附加委托,以重新定义其实现,生成的类为强类型.

2.Shim Types,填充类型,解决了密封类或static成员的问题,T的填充类型ShimT可以为T的每个成员提供一个替代实现

二 、选择原则

由于Stub和Shim的实现方式不同,所以它们也有不同的要求,下面总结了选择它们的一些原则:

性能方面:运行时使用Shim重写会影响性能,Stub由于使用的是虚方法,则无此问题

对static方法/sealed类型:Stub类型只可以重写虚方法,因此,它不适用于static方法/sealed方法/sealed类中的方法,等

Internal类型:对于标记了InternalsVisibleToAttribute的内部类型,Fakes也可以起作用

private方法:如果private方法的签名上的所有类型都是可见类型,那么可以通过Shim来替换实现.Stub只能替换可见方法.

接口和抽象方法:Stub可以提供接口或抽象方法的替代实现.Shim则不能,因为没有实际的方法体.

所以建议在一般情况下使用Stub来支持那些可测试性做的非常好的类型,而用Shim来解决那些耦合很大,可测试性很差的代码或三方组件.

三、如何使用Fakes

假设我们在项目ClassLibrary1中有以下几个类

   1: public interface IDataAccess
   2: {
   3:     int Read();
   4: }
   5:  
   6: public class MyDataAccess : IDataAccess
   7: {
   8:     public int Read()
   9:     {
  10:         return Tools.GetNum();
  11:     }
  12: }
  13:  
  14: public class Tools
  15: {
  16:     static public int GetNum()
  17:     {
  18:         return 1;
  19:     }
  20: }
  21:  
  22: public class MyClass
  23: {
  24:      public static int GetMyData(IDataAccess obj)
  25:      {
  26:          //其它逻辑
  27:          return obj.Read();
  28:      }
  29: }

我们要使用Fakes进行测试只需要在测试项目中引用 ClassLibrary1,并且在之上右键->建立 Fakes即可使用Fakes

 

之后我们就可以使用类似以下代码来模拟一个IDataAccess的实例 ,MyClass.GetMyData  这个static方法的实现

前者即使用Stub,后者即Shim

   1: [TestClass]
   2: public class UnitTest1
   3: {
   4:     [TestMethod]
   5:     public void StubTest()
   6:     {
   7:         IDataAccess stockFeed = new ClassLibrary1.Fakes.StubIDataAccess()
   8:                                     {
   9:                                         Read = () => { return 2; }
  10:                                     };
  11:         Assert.AreEqual(2, MyClass.GetMyData(stockFeed));
  12:  
  13:     }
  14:     [TestMethod]
  15:     public void ShimTest()
  16:     {
  17:         using (ShimsContext.Create())
  18:         {
  19:             ClassLibrary1.Fakes.ShimMyClass.GetMyDataIDataAccess = (inc) => { return 2; };
  20:             Assert.AreEqual(2, MyClass.GetMyData(null));
  21:         }
  22:  
  23:     }
  24:  
  25: }

Stub 与其它Mock差不多,只是使用委托来改变方法实现

而Shim则需要建立 ShimsContext的作用域

2013九月5

源代码跟踪

ASP.NET 评论关闭
2013八月25

关于Redis的常识

ASP.NET 评论关闭
2013八月24

给 C# 开发者的代码审查清单

ASP.NET 评论关闭

给 C# 开发者的代码审查清单

可参考:

1. 确保没有任何警告(warnings)。
2.如果先执行Code Analysis(启用所有Microsoft Rules)再消除所有警告就更好了。
3. 去掉所有没有用到的usings。编码过程中去掉多余代码是个好习惯。
4. 在合理的地方检查对象是否为’null’,避免运行的时候出现Null Reference Exception
5,代码可重用性:如果一块代码已经被使用超过一次,或者你希望将来使用它,请提取成一个方法。将重复的工作做成通用的方法放在相关的类中。
6,确保代码中方法的行数不要过多,不超过30到40行。
7,单元测试

清单

1. 确保没有任何警告(warnings)。

2.如果先执行Code Analysis(启用所有Microsoft Rules)再消除所有警告就更好了。

3. 去掉所有没有用到的usings。编码过程中去掉多余代码是个好习惯。(参考:msdn

4. 在合理的地方检查对象是否为’null’,避免运行的时候出现Null Reference Exception

5. 始终遵循命名规范。一般而言变量参数使用驼峰命名法,方法名和类名使用Pascal命名法。(参考:msdn

6. 请确保你了解SOLID原则。

根据维基百科定义:在程序设计领域,SOLID (单一功能、开闭原则、里氏替换、接口隔离以及依赖反转)是由罗伯特·C·马丁在21世纪早期引入的记忆术首字母缩略字,指代了面向对象编程和面向对象设计的五个基本原则。当这些原则被一起应用时,它们使得一个程序员开发一个容易进行软件维护和扩展的系统变得更加可能。SOLID所包含的原则是通过引发编程者进行软件源代码的代码重构进行软件的代码异味清扫,从而使得软件清晰可读以及可扩展时可以应用的指南。SOLID被典型的应用在测试驱动开发上,并且是敏捷开发以及自适应软件开发的基本原则的重要组成部分。参考:wiki/SOLID_(面向对象设计)

7. 代码可重用性:如果一块代码已经被使用超过一次,或者你希望将来使用它,请提取成一个方法。将重复的工作做成通用的方法放在相关的类中,这样一旦你完成别人就可以使用了。将常用功能开发成用户控件,这样可以跨项目重用它们。(参考: 、 

8. 代码一致性:比方说,Int32写成int,String写成string,应该在代码里保持统一形式。不能一会二写成int一会儿写成Int32。

9. 代码可读性:代码应该是可维护的,便于其他开发者理解。(参考:msdn

10. 释放非托管资源,比如文件I/O,网络资源等。一旦使用结束就应该释放它们。如果你想一旦超出使用范围就自动释放对象,可以使用usings将非托管代码括起来。参考:msdn

11. 合理实现异常处理(try/catch和finally块)和异常记录。参考:msdn

12. 确保代码中方法的行数不要过多,不超过30到40行。

13. 及时用代码管理工具check-in/check-out代码。(比如TFS) 参考:codeproject.com

14. 相互审查代码:和你的同事交换代码,实现内部审查。

15. 单元测试:编写开发测试用例完成单元测试,确保代码被送到QA以前,基本测试完成。参考:msdn

16. 尽量避免for/foreach循环嵌套和if条件嵌套。

17. 如果代码只会使用一次,请使用匿名类型。参考:msdn

18. 尽量使用LINQ查询和Lambda表达式,增加可读性。参考:msdn

19. 合理使用var、object和dynamic关键字。由于很多开发者会感到困惑或者知道的很少,会觉得它们有些相似,故而交换使用,这是要避免的。参考:blogs.msdn

20. 使用访问限定符(private, public, protected, internal, protected internal)限定每个方法、类或变量的需要范围。比方说如果一个类只会在程序集内使用,那么定义成internal就足够了。参考:msdn

21. 在需要保持解耦的地方使用接口,有些设计模式的出现也是由于接口的使用。参考:msdn

22. 按照用法和需要将类定义为sealed、static或abstract。参考:msdn

23. 如果需要多次串联,请使用Stringbuilder代替string,这可以节省堆内存。

24. 检查是否有不可能执行的代码,如果有,请修改。

25. 在每个方法前注释,说明它的用法、输入类型和返回值类型信息。

26. 使用类似Silverlight Spy的工具,检查和操控Silverlight应用在运行时对XMAL的渲染,以此来改善效率。这可以在设计执行XAML时,节省大量退回和来回修改的时间。

27. 使用filddler工具通过检查HTTP/网络流量和带宽,来跟踪web应用和服务的性能。

28. 如果你想确认Visual Studio以外的方法,请使用WCFTestClient.exe工具,或者装载它的进程到Visual Studio来进行调试。

29. 在任何合理的地方使用constants和readonly。参考:/msdnmsdn

30. 尽量避免强制转换和类型转换,因为会造成性能损失。参考:msdn

31. 对于你想提供自定义信息的类,请重载ToString(来自Object类)。参考:msdn

32. 避免直接从其他代码中ctrl+c/ctrl+v。一直建议还是自己用手敲,即使你已经找到相关代码。这样可以锻炼自己写代码能力,还能正确理解那段代码的用法。最终你永远都不会忘记那段代码。

33. 保持阅读书籍和文章的良好习惯,遵循大神们的实践指导。(比如微软专家和一些著名的专家,Martin Fowler, Kent Beck, Jeffrey Ritcher, Ward Cunningham, Scott Hanselman, Scott Guthrie, Donald E Knuth.)

34. 确认代码是否有内存泄漏。如果有,请确保已修正。参考:blogs.msdn.com

35. 尽可能参加专家们组织的技术研讨会,可以接触到最新的软件趋势、技术和最佳实践

36. 要透彻理解OOP概念,并尽可能在代码里实现。

37. 知道项目设计架构,可以从整体上理解程序的执行流程。

38. 采取必要措施阻止避免任何交叉脚本攻击、SQL注入和其他安全漏洞。

39. 永远记得将保密和敏感信息加密(通过使用好的加密算法),比如保存到数据库的密码和保存在web.config文件中的连接字符,要避免被非认证的用户操纵。

40. 避免对已知类型(原始类型)使用默认关键字,比如int, decimal, bool等。多数情况下,如果不确定是值类型还是引用类型,就使用泛型类型(T)。参考:msdn

41. 微软(在代码分析条例和指导中)并不推荐使用’out’和’ref’,这些关键字是通过引用传参,请注意,’ref’参数在传入被调用方法之前,应当在调用方法中先初始化,但’out’参数就不是这样。参考:msdn

2013八月7

缓存:MongoDB redis memcached

ASP.NET 评论关闭

mongodb和memcached不是一个范畴内的东西。mongodb是文档型的非关系型数据库,其优势在于查询功能比较强大,能存储海量数据。mongodb和memcached不存在谁替换谁的问题。



和memcached更为接近的是redis。它们都是内存型数据库,数据保存在内存中,通过tcp直接存取,优势是速度快,并发高,缺点是数据类型有限,查询功能不强,一般用作缓存。在我们团队的项目中,一开始用的是memcached,后来用redis替代。



相比memcached:



1、redis具有持久化机制,可以定期将内存中的数据持久化到硬盘上。



2、redis具备binlog功能,可以将所有操作写入日志,当redis出现故障,可依照binlog进行数据恢复。



3、redis支持virtual memory,可以限定内存使用大小,当数据超过阈值,则通过类似LRU的算法把内存中的最不常用数据保存到硬盘的页面文件中。



4、redis原生支持的数据类型更多,使用的想象空间更大。



5、前面有位朋友所提及的一致性哈希,用在redis的sharding中,一般是在负载非常高需要水平扩展时使用。我们还没有用到这方面的功能,一般的项目,单机足够支撑并发了。redis 3.0将推出cluster,功能更加强大。



6、redis更多优点,请移步官方网站查询。

MongoDB 或者 redis 可以替代 memcached 吗?

2013六月23

短网址实现

ASP.NET 评论关闭

算法原理

1)将长网址md5生成32位签名串,分为4段, 每段8个字节;

2)对这四段循环处理, 取8个字节, 将他看成16进制串与0x3fffffff(30位1)与操作, 即超过30位的忽略处理;

3)这30位分成6段, 每5位的数字作为字母表的索引取得特定字符, 依次进行获得6位字符串;

4)总的md5串可以获得4个6位串; 取里面的任意一个就可作为这个长url的短url地址;

 算法描述:使用6个字符来表示短链接,我们使用ASCII字符中的'a'-'z','0'-'5',共计32个字符做为集合。每个字符有32种状态,六个字符就可以表示32^6(1073741824),那么如何得到这六个字符,描述如下:

对传入的长URL进行Md5,得到一个32位的字符串,这个字符串变化很多,是16的32次方,基本上可以保证唯一性。将这32位分成四份,每一份8个字符,这时机率变成了16的8次方,是4294967296,这个数字碰撞的机率也比较小啦,关键是后面的一次处理。我们将这个8位的字符认为是16进制整数,也就是1*('0x'.$val),然后取0-30位,每5个一组,算出他的整数值,然后映射到我们准备的32个字符中,最后就能够得到一个6位的短链接地址。
 

 

 

参考:

 

短链接算法收集与分析

关于微博内容中的短地址ShortURL

各大微博短网址(ShortUrl)的算法 C#

2013六月20

VS2010测试

ASP.NET 评论关闭
普通单元测试:测试类方法,如值是否相等,逻辑判断是否正确等
顺序单元测试:按指定顺序执行测试
UI界面测试:可以录制操作步骤测试
数据库测试:测试数据库表数据合法
压力测试:测试性能
Generic测试:与其他测试工具混合使用
2013五月23

程序集引用

ASP.NET 评论关闭

1、.NET 框架支持两种程序集:强命名程序集(strongly named assembly)非强命名程序集。
      强命名程序集有一个发布者的公钥/私钥对签名,其中的公钥/私钥对唯一地标识了程序集的发布者。利用公钥/私钥对我们可以对程序集进行唯一的标识、安全策略和版本策略。(由于简单地用文件名导致了目前所谓的DLL Hell,强命名程序集就是CLR用来唯一地标识一个程序集的机制。)

2、一个程序集有两种部署方式:私有方式和全局方式。
     非强命名程序集只能进行私有部署。
     全局部署方式将程序集部署在一些CLR确知的地方,当CLR搜索程序集时,它会知道到这些地方去查找。强命名程序集既可以进行私有部署,也可以进行全局部署。它提供多个应用程序域访问同一个程序集的能力,特别地,内存中只存在该程序集的同一份副本,这种非特定于域的代码共享极大节省了内存资源占用。并且,在大多数情况下,共享程序集安装在全局程序集高速缓冲存储器(Global Assembly Cache)中而不存在于应用程序相关目录下,对它的引用不会产生文件复制,自然也不会产生额外的副本。因而,共享程序集不能简单通过XCOPY命令实现部署,而应使用MSI(Microsoft Windows Installer)进行。当组件和主应用程序不由同一个开发商建立,或者一个大应用程序分布在几个小工程中时,常常需要使用共享程序集。

3,引用流程: 如果文件名包含了完整路径,则 CSC.exe 加载指定路径下的文件。如果指定的是不带路径的文件,它将在以下目录中查找引用的程序集:
       a、当前工作路径;
       b、编译器目前使用的CLR所在的目录。MSCorLib.dll总是包含在该目录中(System.Object就定义在这个程序集中)。该目录类似于:
       C:/Windows/Micorsoft.NET/Framework/v1.0.3427 ;
       c、任何用CSC.exe的 /lib 命令行开关指定的目录;
       d、任何LIB环境变量中指定的目录

       安装.NET框架时,微软的程序集文件会被分别拷贝到 CLR所在目录及 GAC目录中。在CLR所在目录中拷贝是使我们能够方便的生成自己的程序集;GAC中的拷贝则是用于运行时加载这些程序集。

       CSC.exe 不在GAC 中查找所引用的程序集的原因是因为需要指定的路径比较麻烦。
4,可用vs自带的合成日志查看器查看程序集加载过程

5,创建与部署:用SN工具生成强签名,用GACUti部署到全局,这样一个程序集可被多个应用程序访问

2013四月25

二级域名session共享

ASP.NET 评论关闭
一、实现IHttpModule类,见后。

二、修改web.config
添加域名
<appSettings><add key="RootDomain" value=""/></appSettings>
RootDomain cookie域名,若是本地则写空
by design domain names must have at least two dots otherwise browser will say they are invalid
when working on localhost (!) the cookie-domain must be set to "" or NULL or FALSE instead of "localhost"

增加过滤
<system.web>
<sessionState mode="StateServer" stateNetworkTimeout="10" timeout="120" stateConnectionString="tcpip=127.0.0.1:42424" />
 <httpModules>

      <add name="SessionSharedHttpModule" type="ClassLibrary.BasePage.MakeSessionIDOneOnly,ClassLibrary"/>

    </httpModules>
</system.web>

三、附类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.SessionState;
using System.Reflection;
using System.Configuration;

namespace ClassLibrary.BasePage
{
    public class MakeSessionIDOneOnly : IHttpModule
    {
        private string m_RootDomain = string.Empty;

        #region IHttpModule Members

        public void Dispose()
        {

        }

        public void Init(HttpApplication context)
        {
            m_RootDomain = ConfigurationManager.AppSettings["RootDomain"];

            Type stateServerSessionProvider = typeof(HttpSessionState).Assembly.GetType("System.Web.SessionState.OutOfProcSessionStateStore");
            FieldInfo uriField = stateServerSessionProvider.GetField("s_uribase", BindingFlags.Static | BindingFlags.NonPublic);

            if (uriField == null)
                throw new ArgumentException("UriField was not found");

            uriField.SetValue(null, m_RootDomain);

            context.EndRequest += new System.EventHandler(context_EndRequest);
        }

        void context_EndRequest(object sender, System.EventArgs e)
        {
            HttpApplication app = sender as HttpApplication;
            for (int i = 0; i < app.Context.Response.Cookies.Count; i++)
            {
                if (app.Context.Response.Cookies[i].Name == "ASP.NET_SessionId")
                {
                    app.Context.Response.Cookies[i].Domain = m_RootDomain;
                }
            }
        }

        #endregion
    }
}

参考:Session共享的解决方案

2013三月7

数据库缓存

ASP.NET 评论关闭

SqlDependency类有一OnChangeEventHandler方法,可注册委托,当接收到改变时,用委托实施数据更改自动通知前台
例:http://www.360doc.com/content/09/0609/16/32573_3830694.shtml
用此方法可实现删除过期的缓存。要注意的
是command 指定的 commandText 的查询结果发生变化时触发 OnChange,且只触发一次,故需要在触发事件中再次建立依赖和绑定接受通知.sqlDependency start后,会开户一个线程等待,当通知由服务器的service Broker传来的时候,线程收到信息,调用回调函数

sqlDependency的start与stop都是控制线程的开关,注意此线程是全局性的,共享。

不过.net同时有SqlCacheDependency,可自动完成删除缓存的操作。

相关sql:

–订阅
–在做出通知后,会进行删除,所以需要重新订阅
 
select * from sys.dm_qn_subscriptions
 
–信息对接
SELECT TOP 50 * 
FROM sys.transmission_queue

–关掉订阅
KILL QUERY NOTIFICATION SUBSCRIPTION  10

要达到的效果:
将数据库中的数据放到缓存中,当数据变化时,自动通过应用删除缓存
Sql server 7.0/2000下 SqlCacheDependency使用轮询的方式进行缓存失效检查,
Sql server 2005/2008下增加使用查询通知方式进行缓存失效检查。

实施:
参考:http://space.itpub.net/16436858/viewspace-630489
http://www.cnblogs.com/over140/archive/2009/01/15/1376318.html

1.检测是否已经启用Service Broker

  Select DATABASEpRoPERTYEX('数据库名称','IsBrokerEnabled')  — 1 表示已经启用 0 表示没有启用

2.启用Service Broker                   

  ALTER DATABASE 数据库名称 SET ENABLE_BROKER;              

 –WITH ROLLBACK IMMEDIATE;
GO
 

3.给您的数据库访问帐号授予权限

  GRANT SUBSCRIBE QUERY NOTIFICATIONS TO test

  注意:这一步非常重要, 如果没有权限, 数据库改变的通知将无法接收, cache永远都不会被刷新,注意 sa授此权限(ms禁止), 所以,换个数据库访问帐号即可.
或者用:alter authorization on database::[<your_SSB_DB>] to [sa];
4,缓存代码

/// <summary>
    /// 设置表依赖缓存
    /// </summary>
    public static DataTable GetTableCache(string TableName, string CacheDataBase,string ConnStr)
    {
        System.Web.Caching.Cache objCache = HttpRuntime.Cache;
        DataTable dt = new DataTable();
        //objCache.Insert(CacheKey, objObject);
        if (objCache[TableName] == null)
        {
            try
            {
                //get from database
                DataSet ds = new DataSet();
 
                SqlDependency.Start(ConnStr);//启动与关闭放在Global的Application_Start,End中好一些
 
                using (SqlConnection connection = new SqlConnection(ConnStr))
                {
                    //只有sql中指定的字段发生更改时才会提醒。
                    string sql = string.Format(" SELECT ID,ParentID,Name,OrderBy,OrganID FROM dbo.mdCity");
 
                    using (SqlCommand command = new SqlCommand(sql, connection))
                    {
                        SqlCacheDependency dependency = new SqlCacheDependency(command);
 
                        //using (SqlDataAdapter adapter = new SqlDataAdapter()) //查询数据
                        //{
                        //    adapter.SelectCommand = command;
                        //    adapter.Fill(ds);
                        //}
 
                        //HttpRuntime.Cache.Insert("EntityResourceCollection", ds, dependency);
                        connection.Open();
                        dt.Load(command.ExecuteReader(CommandBehavior.CloseConnection));
                        objCache.Insert(TableName, dt, dependency);
                    }
 
                }
 
 
            }
            catch
            {
 
            }
 
        }
        else
        {
            dt = (DataTable)objCache[TableName];
        }
 
        return dt;
    }

5,注意 只有sql中指定字段发生更改时才会提醒。

关于SqlDependency类,它的限制很多,特别要注意的就是command的sql语句问题:
select id,name from dbo.test where id<>4 order by id desc 
他只能支持上面这样的简单语句
表名前需要架构名,如dbo

sql注意

满足下列要求的 SELECT 语句支持查询通知:

  • 必须显式说明 SELECT 语句中提取的列,并且表名必须限定为两部分组成的名称。注意,这意味着语句中引用的所有表都必须处于同一数据库中。
  • 语句不能使用星号 (*) 或 table_name.* 语法指定列。
  • 语句不能使用未命名列或重复的列名。
  • 语句必须引用基表。
  • 语句不能引用具有计算列的表。
  • 在 SELECT 语句中提取的列不能包含聚合表达式,除非语句使用 GROUP BY 表达式。提供 GROUP BY 表达式时,选择列表便可以包含聚合函数 COUNT_BIG() 或 SUM()。但是,不能为可为空的列指定 SUM()。语句不能指定 HAVING、CUBE 或 ROLLUP。
  • 在用作简单表达式的 SELECT 语句中提取的列不能多次显示。
  • 语句不能包含 PIVOT 或 UNPIVOT 运算符。
  • 语句不能包含 UNION、INTERSECT 或 EXCEPT 运算符。
  • 语句不能引用视图。
  • 语句不能包含下列任意一个:DISTINCT、COMPUTE、COMPUTE BY 或 INTO。
  • 语句不能引用服务器全局变量 (@@variable_name)。
  • 语句不能引用派生表、临时表或表变量。
  • 语句不能从其他数据库或服务器中引用表或视图。
  • 语句不能包含子查询、外部联接或自联接。
  • 语句不能引用下列大型对象类型:textntext 和 image
  • 语句不能使用 CONTAINS 或 FREETEXT 全文谓词。
  • 语句不能使用行集函数,包括 OPENROWSET 和 OPENQUERY。
  • 语句不能使用下列任何一个聚合函数:AVG、COUNT(*)、MAX、MIN、STDEV、STDEVP、VAR 或 VARP。
  • 语句不能使用任何具有不确定性的函数,包括排名函数和窗口函数。
  • 语句不能包含用户定义聚合。
  • 语句不能引用系统表或视图,包括目录视图和动态管理视图。
  • 语句不能包含 FOR BROWSE 信息。
  • 语句不能引用队列。
  • 语句不能包含无法更改和无法返回结果的条件语句(如 WHERE 1=0)。
  • 语句不能指定 READPAST 锁提示。
  • 语句不能引用任何 Service Broker QUEUE。
  • 语句不能引用同义词。
  • 语句不能具有基于 double/real 数据类型的比较或表达式。
2013三月3

缓存XML

ASP.NET 评论关闭

将配置信息放到XML中,利用cache放到内存中,同时增加一文件依赖,保证配置文件改变时自动删除缓存。

 private DataTable GetData()
        {
            DataTable tableData = new DataTable();
            if (Cache["data"] == null)
            {
                DataSet ds = new DataSet();
                string filePath = Server.MapPath("~/XMLFile.xml");
                ds.ReadXml(filePath);
                tableData = ds.Tables[0];
                CacheDependency cdy = new CacheDependency(filePath);
                Cache.Insert("data", tableData, cdy);
               
            }
            else
            {
                tableData = (DataTable)Cache["data"];
            }
            return tableData;
        }
    

——-

<?xml version="1.0" encoding="utf-8" ?>
<book>
  <item>
    <bookName>算法设计</bookName>
    <author>清华</author>
  </item>
  <item>
    <bookName>高级数据库技术</bookName>
    <author>中山大学</author>
  </item>
</book>
2013三月2

linq to xml

ASP.NET 评论关闭
  XDocument xdoc = XDocument.Load(@"XMLFile1.xml");
            var product = from u in xdoc.Descendants("product")
                        where u.Parent.Attribute("urlKeyWords").Value.IndexOf("postpar") >= 0
                        select u;
            foreach (var u in product)
            {
                string name = u.Attribute("text").Value;
                Console.WriteLine(name);
            }
            Console.Read();

<?xml version="1.0" encoding="utf-8" ?>

<Products>
<WebSite urlKeyWords="postpartum">
<product text="dd" value="dd" amount ="1000"></product>
<product text="dd1" value="dd1" amount ="2000"></product>
<product text="dd2" value="dd2" amount ="3000"></product>
<product text="dd3" value="dd3" amount ="4000"></product>
</WebSite>
<WebSite urlKeyWords="aaaaaa">
<product text="aa" value="aa" amount ="11"></product>
<product text="aa2" value="aa2" amount ="112"></product>
<product text="aa3" value="aa3" amount ="113"></product>
 
</WebSite>
<WebSite urlKeyWords="bbbbbb">
<product text="bbbb" value="bbbb" amount ="22"></product>
<product text="bbbb22" value="bbbb22" amount ="2222"></product>
</WebSite>
</Products>