利用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
猜你喜欢
- 本文实例为大家分享了wxPython实现计算器的具体代码,供大家参考,具体内容如下# -*- coding: utf-8 -*-######
- 面向对象的程序设计随着程序的设计的复杂性增加,结构化程序设计方法又不够用了。不够用的根本原因是“代码重用”的时候不方便。面向对象的方法诞生了
- 从这一章开始,将进入 PPT 文件的自动化操作。关于 PPT 自动化操作所要实现的目的依然很简单。包括 “PPT的创建&
- 因时间问题不可能一次写的很多,但我们会经常更新,方便大家。希望学习编程的朋友不要因为从网站复制了代码,而不能正常的运行而放弃。其实老鸟也是经
- 1. 概念1.1 基本概念时间,对于我们来说很重要,什么时候做什么?什么时候发生什么?没有时间的概念,生活就乱了。在日常的运维当中,我们更关
- 1. 从官网选择Prometheus版本进行下载官网地址>> https://github.com/prometheus/pro
- 简介网上流传的部分可以百度关键词“Python”和“word”后查看文章学习,以下内容为个人实践,修正了不能运行出错的情况。代码示例impo
- 在需要使用到大批量数据的时候,即可以使用随机数据进行生成操作Faker的介绍Faker是python方向的一个第三方库,主要用来创造伪数据,
- 在前面的DRF系列教程中,我们以博客为例介绍了序列化器, 使用基于类的视图APIView和ModelViewSet开发了针对文章资源进行增删
- 这篇文章主要介绍了flask的orm框架SQLAlchemy查询实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考
- '-----------------------------------------------------------
- 之前对bottle做过不少的介绍,也写过一些文章来说明bottle的缺点,最近发现其实之前有些地方说的不太公平,所以趁此机会也来更正一下。&
- 本文实例讲述了PHP获取当前相对于域名目录的方法。分享给大家供大家参考。具体如下:http://127.0.0.1/dev/classd/i
- 想弄个截屏工具,整理一下学生错题什么的,原来用的方法是:先运行QQ,再监听键盘热键(“ctrl+alt+a”)。后来发现有些问题:需要先上Q
- 1 Python自动绘图在这里我主要运用了pyautocad库进行AutoCAD的自动化操作,pyautocad是一款功能非常强大的Auto
- 网易云音乐排行榜歌曲及评论爬取主要注意问题:selenium 模拟登录、iframe标签定位、页面元素提取。在利用selenium定位元素并
- 本文意在弄清楚这些概念间的关系及其作用。弄清Mysql在开启事务的情况下,每条sql执行时的加锁操作和MVCC版本控制。为使讨论简单,本文忽
- 在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用担心, mysql已经为我们提供了这样一个功
- tkinter是python自带的GUI库,可以实现简单的GUI交互,该例子添加了五种不同效果的Button,如图:from tkinter
- 第一,两者的功能不同。global关键字修饰变量后标识该变量是全局变量,对该变量进行修改就是修改全局变量,而nonlocal关键字修饰变量后