c#winform contentmenustrip

c#winform contentmenustrip,第1张

调用方式:net 20 中 SqlDependency

背景需求:对于数据中表A数据字段的变更,需要引发相应业务逻辑,插入或更新相关表或字段。在以往的方式我们多会在数据库端下文章,建立相应触发器,来完 成业务逻辑 *** 作。不过这种方式仅适用于单纯对于数据 *** 作的需求,可是当我们要完成更复杂的业务需求是却不太容易了(虽然sql05已经支持托管代码的使用 了)。可能你会想到我们可以轮询数据库相关表或视图,来发现数据的变化,可是这对于性能和即时性却是个不容易取舍的问题。不过在 SqlServer2005中有了新的方案,那就是查询通知

      查询通知是在 Microsoft SQL Server 2005 中以及 ADONET 20 的SystemDataSqlClient 命名空间中引入的。查询通知建立在 Service Broker 基础结构的基础上,使应用程序可以在数据更改时收到通知。如果应用程序提供数据库中信息的缓存(例如 Web 应用程序),需要在源数据更改时接收通知,此功能特别有用。

通过三种方式可以使用 ADONET 实现查询通知:

低级实现由 SqlNotificationRequest 类提供,该类公开服务器端功能,使您可以对通知请求执行命令。

高级实现由 SqlDependency 类提供,该类提供源应用程序与 SQL Server 之间通知功能的高级抽象,使您可以使用相关性来检测服务器中的更改。大多数情况下,这是托管客户端应用程序通过适用于 SQL Server 的 NET Framework 数据提供程序利用 SQL Server 通知功能的最简单、最有效的方法。

此外,使用 ASPNET 20(或更高版本)构建的 Web 应用程序可以使用SqlCacheDependency 帮助器类。

      如果应用程序需要通过刷新显示或缓存来响应基础数据中的更改,查询通知非常有用。如果执行相同命令生成的结果集与最初检索到的结果集不同,则 Microsoft SQL Server 可允许 NET Framework 应用程序向 SQL Server 发送命令和请求通知。服务器上生成的通知通过队列发送,供以后处理。

您可以为 SELECT 和 EXECUTE 语句设置通知。使用 EXECUTE 语句时,SQL Server 会为执行的命令而不是 EXECUTE 语句本身注册通知。该命令必须满足 SELECT 语句的要求和限制。当注册通知的命令包含多个语句时,数据库引擎会为批处理中的每个语句创建一个通知。

使用查询通知的应用程序有一组通用的要求。必须正确配置数据源才能支持 SQL 查询通知,并且用户必须具有正确的客户端和服务器端权限。

要使用查询通知,必须符合下列条件:

1使用 SQL Server 2005 或 SQL Server 2008。

2对数据库启用查询通知。

3确保用于连接数据库的用户 ID 具有必要的权限。

4使用 SqlCommand 对象执行有效的 SELECT 语句,包含关联的通知对象 — SqlDependency 或 SqlNotificationRequest。

5提供所监视的数据更改时用于处理通知的代码。

下面就以一个例子来说明使用SqlDependency的整个流程

using System;

using SystemCollectionsGeneric;

using SystemText;

using SystemDataSqlClient;

using SystemData;

using SystemConfiguration;

using SystemWindowsForms;

namespace CaptureWeb

{

public class SQLServiceBroker

{

private string connectionStr = ConfigurationManagerConnectionStrings["ConnectionString"]ToString();

private string sqlStr = "";

private SqlConnection connection = null;

public delegate void UIDelegate();

private UIDelegate uidel = null;

public Form form = null;

/// <summary>

///

/// </summary>

/// <param name="TableName"></param>

/// <param name="ColumnNames"></param>

public SQLServiceBroker(string TableName, List<string> ColumnNames)

{

string columns = "";

foreach (string str in ColumnNames)

{

if (columns != "")

columns = columns + ",";

columns = columns + "[" + str + "]";

}

thissqlStr = stringFormat("select {0} From [dbo][{1}]", columns, TableName);

}

/// <summary>

///

/// </summary>

/// <param name="constr"></param>

/// <param name="TableName"></param>

/// <param name="ColumnNames"></param>

public SQLServiceBroker(string constr, string TableName, List<string> ColumnNames)

: this(TableName, ColumnNames)

{

thisconnectionStr = ConfigurationManagerConnectionStrings[constr]ToString();

}

/// <summary>

///

/// </summary>

~SQLServiceBroker()

{

StopDependency();

connectionDispose();

}

/// <summary>

///

/// </summary>

/// <returns></returns>

public bool EnoughPermission()

{

SqlClientPermission perm = new SqlClientPermission(SystemSecurityPermissionsPermissionStateUnrestricted);

try

{

permDemand();

return true;

}

catch (SystemException)

{

return false;

}

}

/// <summary>

///

/// </summary>

/// <param name="uidelegate"></param>

public void InitDependency(UIDelegate uidelegate)

{

SqlDependencyStop(connectionStr);

SqlDependencyStart(connectionStr);

if (connection == null)

connection = new SqlConnection(connectionStr);

if (!EnoughPermission())

throw new Exception("没有权限(SqlClientPermission)!");

if (uidelegate == null)

throw new Exception("回调方法未指定(UIDelegate)!");

if (connection == null)

throw new Exception("未初始化(InitDependency)!");

thisuidel = uidelegate;

}

/// <summary>

/// 传入窗体对象,以防止委托有需要访问UI层控件是引发的“从不是创建控件的线程访问它”

/// </summary>

/// <param name="form1"></param>

/// <param name="uidelegate"></param>

public void InitDependency(Form form1, UIDelegate uidelegate)

{

InitDependency(uidelegate);

thisform = form1;

}

/// <summary>

///

/// </summary>

public void StartDependency()

{

//这里很奇怪,每次都需要新的command对象

using (SqlCommand command = new SqlCommand(sqlStr, connection))

{

commandNotification = null;

SqlDependency dependency = new SqlDependency(command);

dependencyOnChange += new OnChangeEventHandler(dependency_OnChange);

if (connectionState != ConnectionStateOpen)

connectionOpen();

commandExecuteNonQuery();

commandDispose();

}

}

/// <summary>

///

/// </summary>

public void StopDependency()

{

SqlDependencyStop(connectionStr);

if (connection != null)

connectionClose();

}

/// <summary>

///

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void dependency_OnChange(object sender, SqlNotificationEventArgs e)

{

//注销监测事件

SqlDependency dependency = (SqlDependency)sender;

dependencyOnChange -= dependency_OnChange;

//放在移除事件之后又很大必要,防止ui层调用更新相同表时,进入循环出发调用

//uidelInvoke();

//uidel();

//使用fromInvoke调用防止访问界面控件引发“从不是创建控件的线程访问它”

if (form != null)

formInvoke(uidel);

else

uidel();

//再次启动监听

StartDependency();

}

}

}

调用方式:

SQLServiceBroker broker;

private void button1_Click(object sender, EventArgs e)

{

//需要监测的列

List<string> columns = new List<string>();

columnsAdd("test1");

columnsAdd("test2");

string table = "test";

broker = new SQLServiceBroker(table, columns);

//实例化毁掉函数

SQLServiceBrokerUIDelegate uidel = new SQLServiceBrokerUIDelegate(writeCon);

//初始化,及传入回调函数

brokerInitDependency(uidel);

//初始化,传入窗体对象对于需要委托中访问ui控件的情况

//brokerInitDependency(this, uidel);

//启动监听

brokerStartDependency();

MessageBoxShow("启动");

}

private void writeCon()

{

MessageBoxShow("changed");

}

代码比较简单,都有说明,这里有必要注意几点问题:

1首先需要在SQL Server 2005上执行ALTER DATABASE <DatabaseName> SET ENABLE_BROKER;语句让相应的数据库启用监听服务,以便支持SqlDependency特性。

2对于SqlCommand的cmdText有特殊要求,其中不能用,不能用top,不能用函数,包括聚合函数,不能用子查询,包括where后的子查询,不能用外连接,自连接,不能用临时表,不能用变量,不能用视图,不能垮库,表名之前必须加类似dbo数据库所有者这样的前缀。

3其中在使用当中发现SqlConnection对象应该是一直存在的,因此在此示例中升级为属性,如果将它生命在StartDependency方法体中,出现只能调用一次的情况,因为对于SqlDependency需要connection对象的存在。

4在使用委托传入调用方法是,如果方法有访问界面UI控件的情况,需要传入窗体对象,以formInvoke(uidel);的方式调用,否则会引发“从不是创建控件的线程访问它”异常。

5对于回调函数中需要更新正在监听的表时防止循环调用造成死循环,请在调用委托之前先移除onchange事件dependencyOnChange -= dependency_OnChange;

实例代码已经上传

SQLServiceBroker broker;

private void button1_Click(object sender, EventArgs e)

{

//需要监测的列

List&amp;lt;string&amp;gt; columns = new List&amp;lt;string&amp;gt;();

columnsAdd("test1");

columnsAdd("test2");

string table = "test";

broker = new SQLServiceBroker(table, columns);

//实例化毁掉函数

SQLServiceBrokerUIDelegate uidel = new SQLServiceBrokerUIDelegate(writeCon);

//初始化,及传入回调函数

brokerInitDependency(uidel);

//初始化,传入窗体对象对于需要委托中访问ui控件的情况

//brokerInitDependency(this, uidel);

//启动监听

brokerStartDependency();

//在这里重新查询TEST然后绑定数据

}

private void writeCon()

{

MessageBoxShow("changed");

}

其实只需要改动一点点

如果按照你评论说的那么简单

其实就是下面这3句话解决

public Form2()

{

InitializeComponent();

thiscontextMenuStrip1Opening+=new CancelEventHandler(contextMenuStrip1_Opening);

}

private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)

{

//在这里查询数据库

thiscontextMenuStrip1ItemsAdd("菜单项目1");

thiscontextMenuStrip1ItemsAdd("菜单项目2");

thiscontextMenuStrip1ItemsAdd("菜单项目3");

thiscontextMenuStrip1ItemsAdd("菜单项目4");

thiscontextMenuStrip1ItemsAdd("菜单项目5");

}

创建数据库

选择开始菜单中→程序→Management SQL Server 2008→SQL Server Management Studio命令,打开SQL Server Management Studio窗口,并使用Windows或 SQL Server身份验证建立连接。

在对象资源管理器窗口中展开服务器,然后选择数据库节点

右键单击数据库节点,从d出来的快捷菜单中选择新建数据库命令。

执行上述 *** 作后,会d出新建数据库对话框。在对话框、左侧有3个选项,分别是常规、选项和文件组。完成这三个选项中的设置会后,就完成了数据库的创建工作,

在数据库名称文本框中输入要新建数据库的名称。例如,这里以“新建的数据库”。

在所有者文本框中输入新建数据库的所有者,如sa。根据数据库的使用情况,选择启用或者禁用使用全文索引复选框。

在数据库文件列表中包括两行,一行是数据库文件,而另一行是日记文件。通过单击下面的添加、删除按钮添加或删除数据库文件。

切换到选项页、在这里可以设置数据库的排序规则、恢复模式、兼容级别和其他属性。

切换到文件组页,在这里可以添加或删除文件组。

完成以上 *** 作后,单击确定按钮关闭新建数据库对话框。至此“新建的数据”数据库创建成功。新建的数据库可以再对象资源管理器窗口看到。

支持Postgresql

 主要工作内容如下:

 a)修改comantcmscoresetupSetupServletjava,增加两种类型的数据库。(因jspxcms版权限制暂时不提供代码哈!)

b)修改页面前端webapp\setup\databasejsp,增加postgresql数据库。

c)修改SQL,使其能够在postgresql上能够正常使用。 *** 作方法是先生成Mysql5的数据库,然后通过PowerDesiger逆向生成物理模型,然后转换为Postgresql数据库;最后生成Postgresql数据库创建脚本。

 在这里有几个点要注意。

 c1)Postgresql支持Boolean类型,Mysql不支持,所以应该把所有的包含有is而且是char(1)类型统统修改为BOOL类型,包括其默认值(default Value),如果原来是1则为true,如果是0则为false。

 c2)insert Data的sql语句,按照Postgresql语句进行规范,去掉单引号之类的。

 c3)因为类型的变化,把所有DAO层所有Hiberante的boolean类型,传值由原来的0或者1,修改为false或者true;

 c4)把所有Model层里包含有@Lob的字段,加上@orghibernateannotationsType(type="orghibernatetypeStringClobType")

SystemDataSqlClient 请看

>

在onchange里这样写

SqlDependency dep = (SqlDependency)sender;

depOnChange -= dep_OnChange;

if (eInfo != SqlNotificationInfoInvalid)

{

。。。。。代码 注意 要重新注册

}

如果数据库是SQL Server,可以使用SqlDependency进行缓存:

>

以上就是关于c#winform contentmenustrip全部的内容,包括:c#winform contentmenustrip、各位大神小弟最近在写一个Sqlserver2008的数据库推送消息遇到了如下的问题、postgresql 支持sqldependency么等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/10106757.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存