Linux平台下使用 .NET Core 访问 Access数据库 读取 mdb文件 数据

今天有群友在群里问 C# 能不能在 Linux 下访问 Access数据库

我觉得这很有趣,因此研究折腾了一下,也因为很久没有写博文了,所以特意上来写博文分享经验。

运行环境

  • 操作系统:Ubuntu 22.04.3 LTS (Jammy)
  • 开发工具:Visual Studio 2022 (17.8.0)
  • 运行时版本:.NET Runtime 8.0
  • 依赖库:unixodbcmdbtoolsodbc-mdbtools

依赖库安装

apt-get update
sudo apt-get install unixodbc mdbtools odbc-mdbtools

依赖库版本信息

  • apt list --installed | grep odbc
libodbc1/jammy,now 2.3.9-5 amd64 [installed,automatic]
libodbc2/jammy,now 2.3.9-5 amd64 [installed,automatic]
libodbccr2/jammy,now 2.3.9-5 amd64 [installed,automatic]
libodbcinst2/jammy,now 2.3.9-5 amd64 [installed,automatic]
odbc-mdbtools/jammy,now 1.0.0+dfsg-1 amd64 [installed]
odbcinst1debian2/jammy,now 2.3.9-5 amd64 [installed,automatic]
odbcinst/jammy,now 2.3.9-5 amd64 [installed,automatic]
unixodbc-common/jammy,now 2.3.9-5 all [installed,automatic]
unixodbc/jammy,now 2.3.9-5 amd64 [installed]
  • apt list --installed | grep mdb
liblmdb0/jammy,now 0.9.24-1build2 amd64 [installed,automatic]
libmdb3/jammy,now 1.0.0+dfsg-1 amd64 [installed,automatic]
libmdbsql3/jammy,now 1.0.0+dfsg-1 amd64 [installed,automatic]
mdbtools/jammy,now 1.0.0+dfsg-1 amd64 [installed]
odbc-mdbtools/jammy,now 1.0.0+dfsg-1 amd64 [installed]

Linux平台 下的 ODBC 配置

  • /etc/odbc.ini
[access_db] # 随意命名,会在项目代码里用到它
Description=Microsoft Access Database
Driver=MDBW
ServerName = localhost
Database=/root/Database1.mdb # 按你的实际路径改写,要有读写权限
  • /etc/odbcinst.ini
[MDBW] # 随意,在odbc.ini文件用到它
Description=MDBTools Driver Wide # 随意
Driver=/usr/lib/x86_64-linux-gnu/odbc/libmdbodbcW.so # 按你的实际路径改写
Setup=/usr/lib/x86_64-linux-gnu/odbc/libmdbodbcW.so # 按你的实际路径改写
FileUsage=1
UsageCount=1
[MDBTools]
Description=MDBTools Driver # 随意
Driver=/usr/lib/x86_64-linux-gnu/odbc/libmdbodbc.so # 按你的实际路径改写
Setup=/usr/lib/x86_64-linux-gnu/odbc/libmdbodbc.so # 按你的实际路径改写
FileUsage=1
UsageCount=1
[ODBC]
Trace=1
TraceFile=/tmp/mdb.log # 有写入权限的文件路径

Demo 项目代码

  • OdbcForLinuxTestApp.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RuntimeIdentifiers>linux-x64;win-x64</RuntimeIdentifiers>
<SelfContained>true</SelfContained>
<ProduceReferenceAssembly>false</ProduceReferenceAssembly>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup> <ItemGroup>
<PackageReference Include="System.Data.Odbc" Version="8.0.0" />
<PackageReference Include="System.Data.OleDb" Version="8.0.0" />
</ItemGroup>
</Project>
  • Program.cs
using System.Data;
using System.Data.Common;
using System.Data.Odbc;
using System.Data.OleDb; namespace OdbcForLinuxTestApp; internal sealed class Program
{
static async Task Main(string[] args)
{
string connectionStrings;
if (OperatingSystem.IsWindows())
{
string mdbFile = Path.Combine(AppContext.BaseDirectory, "Database1.mdb");
connectionStrings = $"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={mdbFile}";
}
else
{
//root/Database1.mdb
connectionStrings = "DSN=access_db;";
} await using (DbConnection conn = GetDbConnection(connectionStrings))
{
await conn.OpenAsync();
DbCommand cmd = conn.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "select [ID],[UserName] from Users"; DbDataReader reader = await cmd.ExecuteReaderAsync();
while (await reader.ReadAsync())
{
//The MDBTools does not support the use of column names
string userName = reader.GetString(1);
Console.WriteLine("UserName: " + userName);
}
}
} private static string DbProviderName => OperatingSystem.IsWindows() ? "System.Data.OleDb" : "System.Data.Odbc"; private static DbConnection GetDbConnection(string connectionStrings)
{
RegisterOdbcOrOleDbFactory();
DbProviderFactory dbFactory = DbProviderFactories.GetFactory(DbProviderName);
DbConnection? conn = dbFactory.CreateConnection();
if (conn == null)
{
return OperatingSystem.IsWindows() ? new OleDbConnection(connectionStrings) : new OdbcConnection(connectionStrings);
} conn.ConnectionString = connectionStrings;
return conn;
} private static int _isRegisteredDbFactory;
private static void RegisterOdbcOrOleDbFactory()
{
if (Interlocked.CompareExchange(ref _isRegisteredDbFactory, 1, 0) == 0)
{
string dbProviderName = DbProviderName;
IEnumerable<string> providerInvariantNames = DbProviderFactories.GetProviderInvariantNames();
string? invariantName = providerInvariantNames.FirstOrDefault(x => x.Equals(dbProviderName, StringComparison.InvariantCultureIgnoreCase));
if (string.IsNullOrWhiteSpace(invariantName))
{
DbProviderFactories.RegisterFactory(dbProviderName, OdbcFactory.Instance);
}
}
}
}

编译和发布 Demo 项目代码

准备工作

  • 创建 OdbcForLinuxTestApp 目录
  • 将上述两个代码文件放入 OdbcForLinuxTestApp 目录
  • 安装 .NET SDK 8.0.100

编译和发布

OdbcForLinuxTestApp 目录下,执行命令:

dotnet publish -c Release -f net8.0 -r win-x64 -o ./publish/win-x64 # 如果只考虑 Linux平台,该命令可忽略
dotnet publish -c Release -f net8.0 -r linux-x64 -o ./publish/linux-x64

运行 OdbcForLinuxTestApp

注意:Database1.mdb 数据库文件需要提前放到正确的路径,以 odbc.ini文件Database 配置项为准。

cd ./publish/linux-x64
chmod +x OdbcForLinuxTestApp # 授予可执行权限
./OdbcForLinuxTestApp

输出:

UserName: Allen
UserName: Joy

折腾过程中遇到的问题

  1. 搜了几个配置例子,有的说 libmdbodbc.so/usr/lib 目录下,

    也有的在 /usr/local/lib/odbc 目录下,而我最终是在 /usr/lib/x86_64-linux-gnu/odbc 目录下找到。

  2. mdbtools 不支持使用列名访问,只能用列索引。

其它

在Linux平台下使用.NET Core访问Access数据库读取mdb文件数据的更多相关文章

  1. Linux系统下授权MySQL账户访问指定数据库和数据库操作

    Linux系统下授权MySQL账户访问指定数据库 需求: 1.在MySQL中创建数据库mydata 2.新建MySQL账户admin密码123456 3.赋予账户admin对数据库mydata具有完全 ...

  2. C#_.net core 3.0自定义读取.csv文件数据_解决首行不是标题的问题_Linqtocsv改进

    linqtocsv文件有不太好的地方就是:无法设置标题的行数,默认首行就是标题,这不是很尴尬吗?   并不是所有的csv文件严格写的首行是标题,下面全是数据,我接受的任务就是读取很多.csv报表数据, ...

  3. linux平台下防火墙iptables原理(转)

    原文地址:http://www.cnblogs.com/ggjucheng/archive/2012/08/19/2646466.html iptables简介 netfilter/iptables( ...

  4. Windows 和 Linux 平台下的端口转发工具

    原文地址: http://unmi.cc/windows-linux-port-forwarding/ 这里记录一下我曾经使用过的几个端口转发工具,即端口映射.端口重定向,和 NAT 也是差不多的概念 ...

  5. 在 Linux 平台下使用 JNI

    引言 Java 的出现给大家开发带来的极大的方便.但是,如果我们有大量原有的经过广泛测试的非 Java 代码,将它们全部用 Java 来重写,恐怕会带来巨大的工作量和长期的测试:如果我们的应用中需要访 ...

  6. Windows及Linux平台下的计时函数总结

    本文对Windows及Linux平台下常用的计时函数进行总结,包括精度为秒.毫秒.微秒三种精度的各种函数.比如Window平台下特有的Windows API函数GetTickCount().timeG ...

  7. Thrift在Windows及Linux平台下的安装和使用示例

    本文章也同时发表在个人博客Thrift在Windows及Linux平台下的安装和使用示例上. thrift介绍 Apache Thrift 是 Facebook 实现的一种高效的.支持多种编程语言的R ...

  8. Linux平台下裸设备的绑定:

    Linux平台下裸设备的绑定: 运用RAW绑定 方法一 raw的配置(1) [root@qs-dmm-rh2 mapper]# cat /etc/rc.local #!/bin/sh # # This ...

  9. Linux平台下源码安装mysql多实例数据库

    Linux平台下源码安装mysql多实例数据库[root@linux-node1 ~]# netstat -tlunp | grep 330tcp6 0 0 :::3306 :::* LISTEN 6 ...

  10. 【android开发】如何在Linux平台下安装JDK环境

    原文:http://android.eoe.cn/topic/android_sdk Linux平台JDK安装 本文主要描述如何在Linux平台下安装JDK环境.进入网页:http://www.ora ...

随机推荐

  1. js: 获取Blob的值

    this.ws.onmessage = async (msg) => { console.log('从服务端获取到了数据') // 从真正服务端发送过来的原始数据时在msg中的data字段 co ...

  2. openpyxl 设置某列单元格样式

    1 # 边框线 2 border_set = Border(left=Side(border_style='thin', color='000000'), 3 right=Side(border_st ...

  3. 配置oracle DG

    主库名称:prod1 使用asm存储数据 11.2.03 同一机器备库名称:dg 使用file存储数据 11.2.03 配置备库的参数文件cd $ORACLE_HOME/dbsvi initdg.or ...

  4. 注意!JAVA中的值传递

    前言:今天在解决一个问题时,程序总是不能输出正确值,分析逻辑思路没问题后,发现原来是由于函数传递导致了这个情况. LeetCode 113 问题:给你二叉树的根节点root和一个整数目标和target ...

  5. 创建本地yum仓库

    创建本地yum仓库 1,将镜像挂载到/mnt 如果失败打开虚拟机把设备状态的两个选项打勾 2,切换到客户端的指定目录 3,创建文件夹bak存放网络yum创库配置文件 4,将网络源移动到bak减少干扰 ...

  6. React中setState的使用与同步异步

    在react中,修改状态如果直接使用this.state,不会引起组件的重新渲染,需要通过 this.setState来对组件的属性进行修改. 1.this.setState的两种定义方式 定义初始状 ...

  7. [kafka]部署安装单节点

    前言 kafka 3.0之前的版本需要依赖zookeeper,3.0版本之后可不依赖zookeeper. 基于zookeeper的安装步骤 节点IP:172.50.13.103 kafka版本:2.7 ...

  8. Lithosphere是什么,它解决什么问题?

    这问题很好,一针见血,它解决什么问题? 那这得说说,在IoT应用中,我们会碰到什么问题? 和纯软件项目,互联网项目比,IoT应用项目一个比较大不同的地方,应该是它既要做软件,又要做硬件. 我并不是硬件 ...

  9. valgrind 配合 gdb 调试程序

    在实际研发过程中,可能会遇到过这样的问题:测试通过 valgrind 验证当前代码存在变量未初始化的问题,但仅通过 valgrind 测试报告,研发无法确认具体的应用场景.本文将通过 valgrind ...

  10. KVM下windows由IDE模式改为virtio模式蓝屏 开不开机

    KVM安装Windows默认使用的是qemu虚拟化IDE硬盘模式,在这种情况下,IO性能比较低,如果使用virtio的方式可以提高虚拟机IO性能. 于是我想将这台虚拟机迁移到openstack中管理 ...