Linux平台下使用.NET Core访问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 项目代码

输出:

UserName: Allen
UserName: Joy

编译和发布

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

BASH 复制 全屏

  • 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

相关推荐
van叶~1 分钟前
Linux探秘坊-------5.git
linux·运维·git
手捧向日葵的话语2 分钟前
Linux下的编辑器 —— vim
linux·编辑器·vim
ahuang120212 分钟前
在centos下使用containerd管理容器:5分钟从docker转型到containerd
linux·docker·centos
某风吾起28 分钟前
Linux 消息队列的使用方法
java·linux·运维
Elastic 中国社区官方博客36 分钟前
使用 Elasticsearch 导航检索增强生成图表
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
小金的学习笔记41 分钟前
RedisTemplate和Redisson的使用和区别
数据库·redis·缓存
新知图书1 小时前
MySQL用户授权、收回权限与查看权限
数据库·mysql·安全
文城5211 小时前
Mysql存储过程(学习自用)
数据库·学习·mysql
沉默的煎蛋1 小时前
MyBatis 注解开发详解
java·数据库·mysql·算法·mybatis
呼啦啦啦啦啦啦啦啦1 小时前
【Redis】事务
数据库·redis·缓存