利用C#远程存取Access数据库
发布时间:2024-01-27 01:58:32
一、 技术要点
我们都知道Windows应用程序在运行时会启动一个进程,其总包括若干线程,不同的进程之间通信是开发分布式应用程序所必需的,传统上,这不仅需要深入了解通信流两端上进程的对象,而且还要深入了解低级别协议的宿主、应用程序编程接口以及配置工具等。总之,它是一项需要大量专业知识和经验的复杂任务。
幸好.Net为我们提供了远程处理功能,它所提供的通信方法可以快速而方便地完成上述建立通信的任务。因此,无论是需要快速开发 Web 应用程序,还是要花费更多时间生成关键的企业范围的应用程序,.NET Framework 都会提供支持。通过 .NET 远程处理,客户端应用程序可以使用同一台计算机或其网络中其他任何可用的计算机上的其他进程中的对象。
要使用 .NET 远程处理创建可以让两个对象跨越应用程序直接通信的应用程序,只需生成以下对象即可:
1、 可远程处理的对象。
2、 侦听对该远程对象的请求的应用程序即服务器程序。
3、 对该远程对象发出请求的客户端应用程序。
.Net下不同应用程序中的对象的通信方式有两种:一种是跨应用程序域边界传输对象副本,一种是使用代理交换消息。MarshalByRefObject 是通过使用代理交换消息来进行通信的对象的基类。当跨应用程序使用远程对象时,对象的基类必须是从 MarshalByRefObject 继承。
二、 程序实现
(1)我们先在VS的IDE中创建名为“TestRemoteAccess”的新的解决方案来容纳前述用来实现远程处理的三个项目,首先向解决方案中添加名为“RemoteObject”的类库,然后将默认创建的类名更改为“CRemoteAccess”,并且继承于“MarshalByRefObject”,代码如下:
using System;
using System.Collections.Generic;
using System.Text;
namespace RemoteObject
{
public class CRemoteAccess : MarshalByRefObject
{}
}
我们需要在该对象内创建用于连接和存取本地Access数据库的所有函数,供服务端客户端程序同时调用。用于连接和存取Access数据库的方法这里不再详述,参看附件源码。
首先所有需要向客户端公开的函数其可见性都必须设为 public。变量m_ConnString需要设置为public static,目的是当客户端调用了SetRemoteAccessConnString后将数据库连接字符串保存下来以备在本次连接期间始终能够访问,代码如下:
……
public static string m_ConnString;
……
public void SetRemoteAccessConnString(string Connstr)
{
m_ConnString = Connstr;
}
……
成功连接了Access数据库后我们需要返回数据集给请求的客户端进行显示和编辑,在远程对象中我们声明了几个相关函数:
private void LoadData(string SqlStr, string TableName)
public void SaveData(DataTable ClientDataTable)
public DataTable GetUserTable(string SqlStr, string TableName)
客户端可以传递SQL查询脚本通过调用 GetUserTable来获取相关数据库表的数据,并返回一个DataTable,然后可以将该DataTable附值给DataGridView以便将数据显示出来。GetUserTable通过调用私有的LoadData 函数来完成对数据的获取。SaveData函数用于将编辑过的数据集保存回本地Access数据库文件,代码如下:
……
m_connection.Open();
m_adapter.Update(ClientDataTable);
……
(2)远程对象创建完成,我们需要创建用于侦听该远程对象请求的服务端应用程序。在“TestRemoteAccess”解决方案中新建一个Windows窗体项目名为:“TestServer”,从工具箱中拖拽下几个组件,界面如下所示:
服务器程序TestServer除了具备远程访问对象的能力外,它最主要的作用就是获取实际的Access数据库文件路径,并且设置远程对象的数据库连接字符串。我们必须添加远程对象以及远程处理和网络通讯协议等的类库的引用。在服务器程序启动初始,需要创建远程对象的实例以及注册通信端口,然后调用RemotingConfiguration.RegisterWellKnownServiceType 方法,MSDN中关于该方法的描述是这样的:通过使用给定的参数初始化 WellKnownServiceTypeEntry 的新实例,将服务端上的对象 Type 注册为已知类型,所有知道已注册已知对象的 URI 的客户都可以获取该对象的代理。所谓URI即统一资源标识符 (Uniform Resource Identifier)。代码如下:
……
remotableObject = new RemoteObject.CRemoteAccess();
TcpChannel channel = new TcpChannel(8080);
ChannelServices.RegisterChannel(channel);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemoteObject.CRemoteAccess), "RithiaTestAccessServer", WellKnownObjectMode.Singleton);
……
当选择了要进行存取的Access数据库文件后,我们需要调用远程对象的SetRemoteAccessConnString方法,该方法将保存在本次与服务器程序连接期间连接该Access数据库文件的连接字符串,代码如下:
……
ProviderStr = ProviderStrPart + txtAccessMdbFileName.Text + ";Jet OLEDB:Database Password=" + txtAccessPassword.Text;
……
remotableObject.SetRemoteAccessConnString(ProviderStr);
……
(3)最后我们创建用于连接和请求服务的客户端程序,它会通过调用服务器程序TestServer已经注册的远程对象来获取相关数据集,并将编辑过的数据保存回实际的数据库文件。在“TestRemoteAccess”解决方案中新建一个Windows窗体项目名为:“TestClient”,从工具箱中拖拽下几个组件,界面如下所示:
客户端程序需要知道服务器程序所运行在的计算机名称或IP地址以及侦听的端口号,然后创建远程对象的实例,并且创建DataTable以便接收返回的数据,代码如下:
……
string RemoteURL;
Host = txtHost.Text;
Port = txtPort.Text;
RemoteURL = "tcp://" + Host + ":" + Port + "/RithiaTestAccessServer";
try
{
TcpChannel chan = new TcpChannel();
ChannelServices.RegisterChannel(chan);
remoteObject = (RemoteObject.CRemoteAccess)Activator.GetObject(typeof(RemoteObject.CRemoteAccess), RemoteURL);
RemoteDataTable = new DataTable();
button3.Enabled = false;
}
catch (Exception E)
{
MessageBox.Show(E.Message.ToString());
}
finally
{
}
……
客户端程序根据服务程序所侦听的信道是TCP还是HTTP来注册相应的信道和端口号,并且组合成远程对象的Url,即Url= 信道://主机名:端口号/对象的Uri,然后创建远程对象的实例,就像使用本地对象一样可以对其进行存取,我们可以调用远程对象的GetUserTable方法获取指定查询脚本的结果集,代码如下:
……
RemoteDataTable = remoteObject.GetUserTable(txtSQL.Text, "Test");
dataGridView1.DataSource = RemoteDataTable;
……
保存结果集时仅需简单调用SaveData方法即可,代码如下:
……
remoteObject.SaveData(RemoteDataTable);
……
三、 结果
该程序成功地在Visual Studio .Net 2005及Windows XP SP2下调试运行通过。
源码下载:http://d.download.csdn.net/down/401452/q520525745


猜你喜欢
- 安装1、先安装vscode,然后在扩展中搜索Remote SSH插件并安装。2、我要连接远程Ubuntu系统的服务器,所以需要在服务器上安装
- 首先总结的意义就是让杂乱无章变得更加井然有序,这样在使用的过程思路会更加清晰。数组使用方法注意点:变异方法和非变异方法。即变异方法使用会改变
- 在 Class 块中,成员通过相应的声明语句被声明为 Private(私有成员,只能在类内部调用)
- 相信现在很多人都喜欢玩王者荣耀这款手游,里面好看的皮肤令人爱不释手。那么你有没有想过把王者荣耀高清皮肤设置为壁纸,像下面这样今天就来教大家如
- 前文复习:openCV第一篇openCV第二篇一、Canny边缘检测该边缘检测法步骤如下:使用高斯滤波器,以平滑图像,滤除噪声。计算图像中每
- 关于电子邮件 大学之前,基本不用邮箱,所以基本感觉不到它的存在,也不知道有什么用;然而大学之后,随着认识的人越来越多,知识越来越广
- 前置从https://studygolang.com/dl下载go1.14.6.windows-amd64.msi安装即可,安装路径选择默认
- 也许是这样的。下面我们来推荐一个简单的分页程序,代码和说明见下(两段虚线“-----”间的代码是实现该功能的重要语句):chunfeng.a
- 上次在blueidea上看到一个元素圆角的实现方法,但是那个太复杂了。于是就自己写了一个函数,可以将元素自动圆角,如div层,表格等。共有四
- tpch是TPC(Transaction Processing Performance Council)组织提供的工具包。用于进行OLAP测
- 避坑1:RTX30系列显卡不支持cuda11.0以下版本,具体上限版本可自行查阅:方法一,在cmd中输入nvidia-smi查看方法二:由此
- AttribteError: ‘module' object has no attribute xxx'描述:模块没有相关属
- 有多少次你在考虑怎样设置数据库时感到为难?其实,如果你在Linux上使用MySQL,就不会有这种情况了。在Linux上使用Webmin图形界
- 日期包常用函数time.Now(): 获取当前时间package mainimport ( "fmt&q
- 1>保存为二进制文件,pkl格式import picklepickle.dump(data,open('file_path
- 列名不一定要相同,只要你在HH中列出要插入列的列表跟select from mm表中的选择的列的列表一一对应就可以了,当然两边的数据类型应该
- 本文实例讲述了Python使用Selenium模块模拟浏览器抓取斗鱼直播间信息。分享给大家供大家参考,具体如下:import timefro
- 需要转载的小伙伴转载后请注明转载的地址需要用到的库from bs4 import BeautifulSoupimport requestsi
- 强转int类型会直接对浮点数的小数部分进行截断(无论是正还是负)。还有一种方法是math.ceil和math.floor。无论是正数还是负数
- 最近重温了一下位图分割的相关内容,发现网络上位图分割原理讲得已经很清楚了,但是代码多为C++实现或者Matlab实现,因为需要Python的