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

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

时间:2023-11-22 17:44:53浏览次数:55  
标签:Core amd64 mdb jammy odbc installed mdbtools Linux now

今天有群友在群里问 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 不支持使用列名访问,只能用列索引。

其它

标签:Core,amd64,mdb,jammy,odbc,installed,mdbtools,Linux,now
From: https://www.cnblogs.com/VAllen/p/access-mdb-files-in-linux.html

相关文章

  • linux 合并解压命令
    linux合并命令catxxxx.tar.zip.0**>xxxx.tar.ziplinux下常用解压unzipxxxx.tar.ziptarzxvfxxxx.tar.gz  ......
  • Linux系统下shell的使用
    一、什么是shell文字操作系统与外部最主要的接口就叫做shell。shell是操作系统最外面的一层。shell管理与操作系统之间的交互:等待你输入,向操作系统解释你的输入,并且处理各种各样的操作系统的输出结果。shell提供了你与操作系统之间通讯的方式。这种通讯可以以交互方式(从​​键盘......
  • Linux学习记录:文件查找、打包压缩及解压
    1.文件查找echo命令可以查看变量path的值。locate命令可以让用户快速查找到所需要的文件或目录。与locate命令相比,find命令搜索速度较慢,它并不会索引目录,而是对整个目录进行遍历,这会占用很多系统资源。find命令可以按照文件大小、时间、文件属主、属组、文件类型、文件权限查......
  • Linux系统用户如何添加到用户组
    新增一个用户并添加到指定用户组#检查用户组是否存在,如果组存在则会输出组信息,否则没有任何输出grep<用户组名称>/etc/group#如果用户组不存在则使用如下命令新建用户组:groupadd<用户组名称>#新建用户并将其加入指定用户组,作为其主用户组(每个用户有且只有一个主用户组)useradd......
  • Linux 解压和压缩命令
    1、前言 在Linux系统中可以使用tar和split命令配合使用进行大文件的分卷压缩和解压缩。 2、实例将文件夹STM32F031K6/分卷压缩为100M的文件,可以使用下面命令:$tar-cvzf-STM32F031K6/|split-b100m-STM32F031K6.tar.gz.完成后,会产生相应的分卷压缩文件。如果需......
  • Linux课堂知识总结
    这是学习Linux的第四节课,老师跟我们讲述了Linux的文件权限管理操作。文件的权限针对三类对象进行定义owner属主,缩写ugroup属组,缩写gother其他,缩写o。每个文件针对每类访问者定义了三种主要权限r:Read读w:Write写 x:eXecute执行。文件/目录的权限查看命令为:ls-l,该命令会列......
  • Linux文本三剑客-awk
    目录详解awk基础awk场景选项实验简单输出详解awk是一个强大的linux命令,有强大的文本格式化的能力,好比将一些文本数据转化成专业的Excel表的样式awk基础语法awk[option]'pattern[action]'file...awk参数'条件动作'文件action值得是动作,awk擅长文......
  • Linux操作(第十一周)
    本周学习了第六章IO重定向与管道,IO重定向是Linux系统中非常有用的功能,它允许我们将命令的输入和输出重定向到不同的位置,而不是默认的标准输入(stdin)和标准输出(stdout)。标准输入重定向:<符号用于将一个文件作为命令的输入。例如,command<input.txt会将input.txt文件的内容作为co......
  • Linux操作(第十二周)
    本周学习了新章节文件系统与磁盘管理,首先通过lsblk命令用于列出系统中的块设备(如磁盘和分区)信息。以下是一些常用的lsblk命令选项:lsblk:列出所有块设备的信息。lsblk-a:显示所有块设备,包括空设备。lsblk-f:显示块设备的文件系统类型。lsblk-m:以可读的方式显示块设备的大小。ls......
  • Linux操作系统no.9
    第七章:存储管理:1.lsblk命令查看硬盘状态2.fdisk-l 命令可以查看系统所挂硬盘个数以及其分区情况3.使用fdisk命令对sdc硬盘进行分区, 输入“m”参数可以查看帮助信息,了解每个参数的具体作用,分区操作等等 输入“n”参数尝试创建新的分区 输入“p”参数查看硬盘中的分区......