翼度科技»论坛 编程开发 .net 查看内容

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

6

主题

6

帖子

18

积分

新手上路

Rank: 1

积分
18
今天有群友在群里问 C# 能不能在 Linux 下访问 Access数据库?
我觉得这很有趣,因此研究折腾了一下,也因为很久没有写博文了,所以特意上来写博文分享经验。
运行环境


  • 操作系统:Ubuntu 22.04.3 LTS (Jammy)
  • 开发工具:Visual Studio 2022 (17.8.0)
  • 运行时版本:.NET Runtime 8.0
  • 依赖库:unixodbc、mdbtools、odbc-mdbtools
依赖库安装
  1. apt-get update
  2. sudo apt-get install unixodbc mdbtools odbc-mdbtools
复制代码
依赖库版本信息


  • apt list --installed | grep odbc
  1. libodbc1/jammy,now 2.3.9-5 amd64 [installed,automatic]
  2. libodbc2/jammy,now 2.3.9-5 amd64 [installed,automatic]
  3. libodbccr2/jammy,now 2.3.9-5 amd64 [installed,automatic]
  4. libodbcinst2/jammy,now 2.3.9-5 amd64 [installed,automatic]
  5. odbc-mdbtools/jammy,now 1.0.0+dfsg-1 amd64 [installed]
  6. odbcinst1debian2/jammy,now 2.3.9-5 amd64 [installed,automatic]
  7. odbcinst/jammy,now 2.3.9-5 amd64 [installed,automatic]
  8. unixodbc-common/jammy,now 2.3.9-5 all [installed,automatic]
  9. unixodbc/jammy,now 2.3.9-5 amd64 [installed]
复制代码

  • apt list --installed | grep mdb
  1. liblmdb0/jammy,now 0.9.24-1build2 amd64 [installed,automatic]
  2. libmdb3/jammy,now 1.0.0+dfsg-1 amd64 [installed,automatic]
  3. libmdbsql3/jammy,now 1.0.0+dfsg-1 amd64 [installed,automatic]
  4. mdbtools/jammy,now 1.0.0+dfsg-1 amd64 [installed]
  5. odbc-mdbtools/jammy,now 1.0.0+dfsg-1 amd64 [installed]
复制代码
Linux平台 下的 ODBC 配置


  • /etc/odbc.ini
  1. [access_db] # 随意命名,会在项目代码里用到它
  2. Description=Microsoft Access Database
  3. Driver=MDBW
  4. ServerName = localhost
  5. Database=/root/Database1.mdb # 按你的实际路径改写,要有读写权限
复制代码

  • /etc/odbcinst.ini
  1. [MDBW] # 随意,在odbc.ini文件用到它
  2. Description=MDBTools Driver Wide # 随意
  3. Driver=/usr/lib/x86_64-linux-gnu/odbc/libmdbodbcW.so # 按你的实际路径改写
  4. Setup=/usr/lib/x86_64-linux-gnu/odbc/libmdbodbcW.so # 按你的实际路径改写
  5. FileUsage=1
  6. UsageCount=1
  7. [MDBTools]
  8. Description=MDBTools Driver # 随意
  9. Driver=/usr/lib/x86_64-linux-gnu/odbc/libmdbodbc.so # 按你的实际路径改写
  10. Setup=/usr/lib/x86_64-linux-gnu/odbc/libmdbodbc.so # 按你的实际路径改写
  11. FileUsage=1
  12. UsageCount=1
  13. [ODBC]
  14. Trace=1
  15. TraceFile=/tmp/mdb.log # 有写入权限的文件路径
复制代码
Demo 项目代码


  • OdbcForLinuxTestApp.csproj
  1. <Project Sdk="Microsoft.NET.Sdk">
  2.   <PropertyGroup>
  3.     <OutputType>Exe</OutputType>
  4.     <TargetFramework>net8.0</TargetFramework>
  5.     <ImplicitUsings>enable</ImplicitUsings>
  6.     <Nullable>enable</Nullable>
  7.     <RuntimeIdentifiers>linux-x64;win-x64</RuntimeIdentifiers>
  8.     <SelfContained>true</SelfContained>
  9.     <ProduceReferenceAssembly>false</ProduceReferenceAssembly>
  10.     <AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
  11.     <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
  12.   </PropertyGroup>
  13.   <ItemGroup>
  14.     <PackageReference Include="System.Data.Odbc" Version="8.0.0" />
  15.     <PackageReference Include="System.Data.OleDb" Version="8.0.0" />
  16.   </ItemGroup>
  17. </Project>
复制代码

  • Program.cs
  1. using System.Data;
  2. using System.Data.Common;
  3. using System.Data.Odbc;
  4. using System.Data.OleDb;
  5. namespace OdbcForLinuxTestApp;
  6. internal sealed class Program
  7. {
  8.     static async Task Main(string[] args)
  9.     {
  10.         string connectionStrings;
  11.         if (OperatingSystem.IsWindows())
  12.         {
  13.             string mdbFile = Path.Combine(AppContext.BaseDirectory, "Database1.mdb");
  14.             connectionStrings = $"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={mdbFile}";
  15.         }
  16.         else
  17.         {
  18.             //root/Database1.mdb
  19.             connectionStrings = "DSN=access_db;";
  20.         }
  21.         await using (DbConnection conn = GetDbConnection(connectionStrings))
  22.         {
  23.             await conn.OpenAsync();
  24.             DbCommand cmd = conn.CreateCommand();
  25.             cmd.CommandType = CommandType.Text;
  26.             cmd.CommandText = "select [ID],[UserName] from Users";
  27.             DbDataReader reader = await cmd.ExecuteReaderAsync();
  28.             while (await reader.ReadAsync())
  29.             {
  30.                 //The MDBTools does not support the use of column names
  31.                 string userName = reader.GetString(1);
  32.                 Console.WriteLine("UserName: " + userName);
  33.             }
  34.         }
  35.     }
  36.     private static string DbProviderName => OperatingSystem.IsWindows() ? "System.Data.OleDb" : "System.Data.Odbc";
  37.     private static DbConnection GetDbConnection(string connectionStrings)
  38.     {
  39.         RegisterOdbcOrOleDbFactory();
  40.         DbProviderFactory dbFactory = DbProviderFactories.GetFactory(DbProviderName);
  41.         DbConnection? conn = dbFactory.CreateConnection();
  42.         if (conn == null)
  43.         {
  44.             return OperatingSystem.IsWindows() ? new OleDbConnection(connectionStrings) : new OdbcConnection(connectionStrings);
  45.         }
  46.         conn.ConnectionString = connectionStrings;
  47.         return conn;
  48.     }
  49.     private static int _isRegisteredDbFactory;
  50.     private static void RegisterOdbcOrOleDbFactory()
  51.     {
  52.         if (Interlocked.CompareExchange(ref _isRegisteredDbFactory, 1, 0) == 0)
  53.         {
  54.             string dbProviderName = DbProviderName;
  55.             IEnumerable<string> providerInvariantNames = DbProviderFactories.GetProviderInvariantNames();
  56.             string? invariantName = providerInvariantNames.FirstOrDefault(x => x.Equals(dbProviderName, StringComparison.InvariantCultureIgnoreCase));
  57.             if (string.IsNullOrWhiteSpace(invariantName))
  58.             {
  59.                 DbProviderFactories.RegisterFactory(dbProviderName, OdbcFactory.Instance);
  60.             }
  61.         }
  62.     }
  63. }
复制代码
编译和发布 Demo 项目代码

准备工作


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

在 OdbcForLinuxTestApp 目录下,执行命令:
  1. dotnet publish -c Release -f net8.0 -r win-x64 -o ./publish/win-x64 # 如果只考虑 Linux平台,该命令可忽略
  2. dotnet publish -c Release -f net8.0 -r linux-x64 -o ./publish/linux-x64
复制代码
运行 OdbcForLinuxTestApp

注意:Database1.mdb 数据库文件需要提前放到正确的路径,以 odbc.ini文件 的 Database 配置项为准。
  1. cd ./publish/linux-x64
  2. chmod +x OdbcForLinuxTestApp # 授予可执行权限
  3. ./OdbcForLinuxTestApp
复制代码
输出:
  1. UserName: Allen
  2. UserName: Joy
复制代码
折腾过程中遇到的问题


  • 搜了几个配置例子,有的说 libmdbodbc.so 在 /usr/lib 目录下,
    也有的在 /usr/local/lib/odbc 目录下,而我最终是在 /usr/lib/x86_64-linux-gnu/odbc 目录下找到。
  • mdbtools 不支持使用列名访问,只能用列索引。
其它


来源:https://www.cnblogs.com/VAllen/archive/2023/11/22/access-mdb-files-in-linux.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具