依赖库:unixodbc、mdbtools、odbc-mdbtools
apt-get update sudo apt-get install unixodbc mdbtools odbc-mdbtools
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]2.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]
[access_db] # 随意命名,会在项目代码里用到它 Description=Microsoft Access Database Driver=MDBW ServerName = localhost Database=/root/Database1.mdb # 按你的实际路径改写,要有读写权限2. /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 # 有写入权限的文件路径
<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>
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"; // 堆代码 duidaima.com 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 项目代码
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
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 目录下找到。