我真是OLD到死,虽然记得以前肯定看到过INTERSECT/EXCEPT这两个关键字,前不久还在羡慕Oracle有+/-集合操作符而SQL Server怎么竟然没有。。。现在想想难怪当初微软面试的时候面试官告诉我最好了解一下SQL Server 2005新的函数。。。
下面翻译一下http://www.sqlstuff.dk/post/intersect-except-versus-in-not-in.aspx,对INTERSECT/EXCEPT与IN/NOT IN进行比较。
SQL Server有两个有用的,用于找到两个表之间共有与差异行的函数:EXCEPT与INTERSECT。EXCEPT返回属于第一个表而不属于第二个表的行,而INTERSECT返回第一个和第二个表的交集。但它们的性能如何?
实际生活中我发现我很少有机会比较两个拥有完全相同数据列的表,但偶尔也会有这种需求。(难道这两个函数基本只在面试和考试中派用场。。。?)但是大多数情况下,这些行都有主键或其他索引,所以我一般自己只用IN和NOT IN。
为了测试,我建立了两个测试表:
DECLARE @I INT
SET @I = 0
WHILE @I < 10000 BEGIN
IF @I % 5 <> 0
INSERT INTO Table1 VALUES (@I, REPLICATE('A', 10))
IF @I % 4 <> 0 INSERT
INTO Table2 VALUES (@I, REPLICATE('A', 10))
SET @I = @I + 1
END
我没有建立索引。
接下来我要查询属于表1不属于表2的行。由于我知道ID是一个唯一键(unique key),就只适用NOT IN。
SELECT *
FROM Table1
WHERE ID NOT IN (
SELECT ID FROM Table2
)
GO
SELECT * FROM Table1
EXCEPT
SELECT * FROM Table2
GO
这样是人都知道肯定NOT IN效率差的。比率差不多是23% vs. 77%,3.3倍左右。
如果我不仅需要确认ID,还需要确认VALUE,查询语句如下:
SELECT *
FROM Table1
WHERE ID NOT IN (
SELECT ID FROM Table2
)
OR [Value] NOT IN (
SELECT [Value] FROM Table2
)
GO
SELECT * FROM Table1
EXCEPT
SELECT * FROM Table2
GO
差异进一步拉大。22% vs. 78%。
INTERSECT的结果也大同小异。
posted @
2009-11-17 15:46 Dem 阅读(16) |
评论 (0) |
编辑
http://www.sellsbrothers.com/writing/ResourcesAndWinForms.htm
资源(A resource)是在Build期间被绑定在程序集里的命名数据。例如,你可以在你的应用程序中是用如下方式,通过载入文件系统中的图片,来设置背景图片:
public MainForm() {
InitializeComponent();
this.BackgroundImage = new Bitmap(@"C:\WINDOWS\Web\Wallpaper\Azul.jpg");
}
这段代码的问题当然是,不是所有的用户的Windows中都有Azul.jpg,而那些即使有的也很可能不在同一位置。即使你把图片放到你的应用程序中,一个很在意空间的用户很可能决定移出它,导致你的应用程序出现故障(这个原因好像有些扯,敢硬删应用程序文件夹内容的用户自然必须承受这个代价,虽然以前这种事情我也干过。。。)。唯一保险的方式就是确保把图片,或其他文件作为一个资源文件嵌入。你可以使用两种方式来实现。一种方式是在你的项目的Solution Explorer中右键点击,添加一个存在的项目,然后选中你想要嵌入的文件。这个文件就会被复制到你的项目的文件夹,但依然不会被嵌入。要作为资源嵌入项目,你需要右键点击文件,选择属性,在属性中找到“Embedded Resource”的选项。这样做完了之后就能够在运行时载入这个文件。很多.NET类提供了使用资源标识的构造函数,例如Bitmap:
public MainForm() {
InitializeComponent();
this.BackgroundImage = new Bitmap(this.GetType(), "Azul.jpg");
}
当作为一个资源被嵌入后,资源的完整名称会由项目的默认命名空间与文件名组成,例如MySecondApp.Azul.jpg。当图片在运行时被载入时,第一个参数是那个资源的类型,然后是名字的字符串。
当然,如果你直接地想在设计器看到作为背景的效果,你可以使用Property Browswer,而完全不用写载入资源的代码。例如对于背景图片,就是BackgroundImage property。这样设计器就会自动生成代码:
namespace MySecondApp {
public class MainForm : System.Windows.Forms.Form {
public MainForm() {
InitializeComponent();
}
private void InitializeComponent() {
System.Resources.ResourceManager resources =
new System.Resources.ResourceManager(typeof(MainForm));
...
this.BackgroundImage =
(Bitmap)resources.GetObject("$this.BackgroundImage");
...
}
...
}
在这个例子中,不是直接使用了Bitmap构造函数,而是使用了ResourceManager类。这个类可以在运行时直接访问区域性特定资源,不管资源是不是在程序集中。这样Form部署的世后就不需要改动代码或重新编译了。
另外project的Properties下默认有一个Resources.resx Resource文件。WinForm窗体默认有一个resx文件跟随。resx文件是个resource文件,即程序资源文件。
调用的时候可以这样调用:
this.BackgroundImage = global::NamespaceName.Properties.Resources.resourcename;
posted @
2009-11-16 15:45 Dem 阅读(100) |
评论 (0) |
编辑
http://www.codeproject.com/KB/cs/applicationcontextsplash.aspxhttp://weblogs.asp.net/justin_rogers/archive/2004/04/11/111162.aspx 1. 简介
对于开发者,我们总是想要在我们的应用程序中加入一些很酷的功能。这是我们程序员血液中无法抑制的天性本能。要不然我们早就改行做审计或销售了。对于Winform应用程序,增加酷的功能的方法之一是在应用程序启动前增加闪屏功能。
2. Application Context(应用程序上下文):它到底干些啥?
我首先花点时间说一下概念性的东西。如果了解我们的继承类在背后干了些什么会对理解有很大帮助。如果你对这些不感兴趣请跳过这章。
每个WinForms应用程序都有一个ApplicationContext类的实例,你可能只是不知道而已。我们来看一个WinForms的标准的Main()函数:
static void Main()
{
Application.Run(new Form1());
}
你肯定看到过这个。不过你知道这个函数也能写成如下的形式?:
static void Main()
{
ApplicationContext appCtx = new ApplicationContext(new Form1());
Application.Run(appCtx);
}
(我试过了,的确可以)
在前一个例子中,Application.Run函数只是创建了一个新的ApplicationContext实例,然后把Form对象传递给它的构造函数(constructor)。在后一个例子中,我们只是手动进行了这个步骤。所以从现在开始,请记住每个WinForm应用程序有一个ApplicationContext实例,它包含着Main Form的实例。ApplicationContext的目的就是作为你应用程序的Main Form和UI线程之间的应用程序启动与终结的标识链接(notification link )。UI线程是你的应用程序用户界面所在的主线程,它负责处理应用程序的消息循环。这个消息队列接收来自操作系统的事件消息,例如鼠标右键点击,空格键被按下了,并把这些消息发送给了需要处理这些消息的Form。
消息循环是在ThreadContext类之中。这是一个私有的子类,定义在Application类之内。关于ThreadContext的内部机理的介绍非常少,不过你可以使用Anikrino工具(我也不知道是啥,有兴趣的google吧)来深入研究。
让我们返回Main函数。当Main()调用了Application.Run,它接着就会调用ThreadContext.RunMessageLoop,传递到新创建的ApplicationContext实例,而这个ApplicationContext实例中包含了应用程序的Main Form实例。然后RunMessageLoop注册了ThreadContext的回叫函数OnAppThreadExit函数在ApplicationContext的ExitThread事件后触发。这就让消息循环能得知用户什么时候关闭了应用程序的Main Form。接着RunMessageLoop把Main Form的Visible属性设置为true,这样用户就能最终看到Main Form。最后RunMessageLoop的工作就是进入真实的消息循环,开始接收和处理来自操作系统的事件消息。
(好像有点乱,我来整理一下:
Main() call Application.Run
|
/
ThreadContext.RunMessageLoop
|
/
pass in ApplicationContext instance(contain main form)
|
/
ThreadContext.RunMessageLoop call ThreadContext.OnAppThreadExit
|
/
ThreadContext.RunMessageLoop set main form visible=true
|
/
ThreadContext.RunMessageLoop start actual message loop
)
ApplicationContext类只有一个属性:MainForm。在我们之前看过的Main函数范例中,我们传入ApplicationContext构造函数的Form实例设置(get set to)了MainForm属性。set_MainForm属性会注册ApplicationContext.OnMainFormDestroy回叫函数在HandleDestroyed事件(用户关闭Form)后触发。那样ApplicationContext就知道应用程序main form什么时候被销毁。
这个回叫对于Windows应用程序非常重要。Forms不是应用程序,他们只是Application对象保持引用的对象。如果Application对象不知道什么时候main form被销毁,那么它会永无止境地运行消息循环。因此当用户关闭了main form,form会发起它自己的HandleDestroyed事件,而这个事件会调用ApplicationContext的OnMainFormDestroy回叫函数。这个回叫函数接着发起ThreadContext的ExitThread事件,调用ThreadContext的OnAppThreadExit回叫函数。而调用这个函数告诉ThreadContext应用程序的main form已经被销毁,它可以终结UI线程了。最后把应用程序的关闭消息返回给操作系统,清空所有资源,终结UI线程。(过程真纠结。。。。)
3. 根据上面的概念来创建一个闪屏
上面有些说得太多了,不过这有助于你来理解接下来我们究竟要做些什么。
微软本可以不暴露出ApplicationContext类来给我们使用,但他们最终还是暴露了出来。因此我们能继承然后自定义这个启动过程。本文中我们就会创造一个自定义的ApplicationContext,包括两个Form,一个闪屏Form,一个main form。
另外新建一个Class SplashAppContext.cs,这个SplashAppContext类继承ApplicationContext类。
ApplicationContext有两个构造函数ApplicationContext()与ApplicationContext(Form),后者在初始一个新的ApplicationContext实例的同时还会附带一个指定的Form。如果使用了这个构造函数,可能需要重载OnMainFormClosed函数,不然线程的消息循环会在MainForm关闭时随之关闭。
代码如下:
class SplashAppContext:ApplicationContext
{
Form mainForm = null;
Timer splashTimer = new Timer();
public SplashAppContext(Form mainForm, Form splashForm)
: base(splashForm)
{
this.mainForm = mainForm;
splashTimer.Tick += new EventHandler(splashTimer_Tick);
splashTimer.Interval = 10000;
splashTimer.Enabled = true;
}
void splashTimer_Tick(object sender, EventArgs e)
{
splashTimer.Enabled = false;
splashTimer.Dispose();
base.MainForm.Close();
}
protected override void OnMainFormClosed(object sender, EventArgs e)
{
if (sender is Splash)
{
base.MainForm = this.mainForm;
base.MainForm.Show();
}
else if (sender is Main)
{
base.OnMainFormClosed(sender, e);
}
}
}
之前提到过的Timer的知识就是应用在这个上面的,回忆不起来用法的可以参考http://www.cnblogs.com/galaxyyao/archive/2009/10/04/1577860.html。关于
public SplashAppContext(Form mainForm, Form splashForm)
: base(splashForm)
这段,感谢renyu同学的解释。它会先运行父类的方法再运行子类的方法。因为是base(splashForm),所以会先创建一个splashForm,开启计时器splashTimer,然后创建一个mainForm。
少女计时中。。。(这是一个neta,请54)
当计时器到点,触发base.MainForm.Close(),但由于OnMainFormClosed被重载过,所以在关闭时还会检查一下是不是splashForm。如果是splashForm的话,换最终要显示的mainForm显示,然后splashForm自己dispose销毁。
最后我们打开包含Main函数的Program.cs,把Application.Run(new Main());替换成自定义的ApplicationContext:
SplashAppContext splashContext = new SplashAppContext(new Main(), new Splash());
Application.Run(splashContext);
这样,一个简单的闪屏程序就完成了。
posted @
2009-10-28 19:36 Dem 阅读(74) |
评论 (0) |
编辑
摘要: 基于http://msdn.microsoft.com/en-us/magazine/cc163672.aspx与MSDN你强烈地希望把你的应用程序的闪屏加上令人激动的“Funky Cold Medina”(为了让你们之中不是80后的人听懂,我解释一下这是Tone Loc的歌)。在Visual Studio 2005之前,即使在你的应用程序中加入最简单的曲调和系统声音也是一...
阅读全文
posted @
2009-10-02 19:20 Dem 阅读(46) |
评论 (0) |
编辑
摘要: 如果是Linux客户端连SQL Server。。。其实最好的方法就是不用SQL Server当数据库。。。推荐MySQL。但万一真的有需求要用怎么办?第一建议是使用SUSE Linux。毕竟有过协议,SUSE Linux有微软官方的支持何推荐,使用SQL Server JDBC Driver。The Microsoft SQL Server JDBC Driver is designed to w...
阅读全文
posted @
2009-09-24 16:44 Dem 阅读(52) |
评论 (0) |
编辑
摘要: http://blogs.msdn.com/psssql/archive/2009/09/11/fun-with-locked-pages-awe-task-manager-and-the-working-set.aspx我知道关于“Locked Pages”,AWE的话题会非常令人困惑。任何人被这个搞晕头我都会认为非常正常。但我也知道我们已经无数遍地发博客和讨论过这个话题...
阅读全文
posted @
2009-09-24 14:25 Dem 阅读(77) |
评论 (0) |
编辑
摘要: 首先要说明两个概念:1. Windows Security Center这个东西的概念似乎是从Vista开始的。反正就是整合了防火墙,系统更新,防毒软件等等的综合平台。2. Windows 管理规范(Windows Management Instrumentation)是一项核心的 Windows 管理技术;用户可以使用 WMI 管理本地和远程计算机。WMI 通过编程和脚本语言为日常管理提供了一条...
阅读全文
posted @
2009-09-16 00:21 Dem 阅读(48) |
评论 (0) |
编辑
摘要: System.Diagnostics命名空间中的一个类。其实就相当于一个秒表。可以不止停一次。Start方法是按下秒表开始计时,Stop方法是再次按下秒表暂停计时,IsRunning属性来判断秒表是否在运行,Reset方法将秒表清零。它的机制如下:如果已安装的硬件或操作系统提供了高分辨率(high-resolution)的计数器,就用那个计数器;不然就系统计时器。Frequency和IsHighR...
阅读全文
posted @
2009-09-14 14:05 Dem 阅读(43) |
评论 (0) |
编辑