ODBC是什么?
ODBC是什么?我也不知道,用摘抄一个互联网上的话来解释:ODBC英文全称为:Open Database Connectivity。用于在不同的操作系统和数据库管理系统之间进行数据访问的标准化接口。它提供了一组函数和API,使得应用程序可以通过统一的方式访问不同类型的数据源。大多数数据源都有适用的 ODBC 驱动程序。
那么ODBC和ADO.NET以及JDBC的关系是什么?让GPT来回答一下吧:
ODBC(Open Database Connectivity)和ADO.NET(ActiveX Data Objects .NET)是 Microsoft 开发的数据库访问接口。而 JDBC(Java Database Connectivity)则是由 Sun Microsystems 开发的 Java 数据库访问标准。
ODBC 和 JDBC 都提供了一种通用的方式来访问数据库,允许开发人员使用标准 SQL 语句来操作各种不同类型的数据库。ADO.NET则是微软针对 .NET 平台开发的数据库访问接口,提供了与 ODBC 类似的功能,但更加面向对象,具有更好的性能和可扩展性。
为什么要使用ODBC而不使用EFCore?
我也想使用EFCore或者其他的ORM框架,但是走不通!首先场景是这样子的,我们业务中有一个地方需要去连接甲方的数据库,然后查询数据,这个时候我们是使用的System.Data.SqlClient+Dapper来执行SQL查询的,可是一直报错,大概信息就是类似下面这些
// 因为修改了好几次,所以信息我已经对不上了,大概出现了下面的这些
Connection Timeout Expired. The timeout period elapsed during the post-login phase. The connection could have timed out while waiting for server to complete the login process and respond; Or it could have timed out while attempting to create multiple active connections. The duration spent while attempting to connect to this server was - [Pre-Login] initialization=3; handshake=10; [Login] initialization=0; authentication=0; [Post-Login] complete=14074;
或者
Microsoft.Data.SqlClient.SqlException (0x80131904): A connection was successfully established with the server, but then an error occurred during the pre-login handshake.
(provider: SSL Provider, error: 31 - Encryption(ssl/tls) handshake failed)
System.IO.EndOfStreamException: End of stream reached
或者
SSL Handshake failed with OpenSSL error - SSL_ERROR_SSL。
遇到这个问题,我们首先想在连接字符串上操作去修复解决这个问题,但是最后没有解决,我们想在公司复现,首先直接在我自己电脑本地连接sqlserver2019是没有问题的,然后没办法又在服务器安装了sqlserver2008也没有问题(这里我还傻不拉几想着使用容器部署一个sqlserver2008快,然后信了一个博客老哥的鬼话去拉取他的镜像,结果拉取下来是2019版本的,后来查阅资料才知道sqlserver2008哪里有什么镜像),然后又模拟正式环境容器化部署,然后终于复现了上面的错误,然后就开始尝试,我们也在网络上查阅了资料,终于在一个文章上看到sqlserver2008不支持TLS1.2,然后按照那个文档的方法去降低容器TSL版本,比如dockerfile增加
RUN sed -i 's/MinProtocol = TLSv1.2/MinProtocol = TLSv1/g' /etc/ssl/openssl.cnf
RUN sed -i 's/MinProtocol = TLSv1.2/MinProtocol = TLSv1/g' /usr/lib/ssl/openssl.cnf
结果还是不行,错误变了,继续查阅文章,然后终于找到【嘿dotNet】公众号老哥的一个博客,他在2019年遇到了这个问题,我将他总结性的那部分摘抄出来
.net core 的System.Data.SqlClient支持的最低SqlServer版本是2008 r2 SP3,小于这个版本的就会报这个错。
来源:https://github.com/dotnet/corefx/issues/9719
结论:.netcore 连接使用sqlserver遇到以上报错1、报错2的同学,需注意:**.net core 的System.Data.SqlClient支持的最低SqlServer版本是2008 r2 SP3**请先检查数据库版本。
呼~这个鬼问题浪费了我整整两天+(3个熬夜)
文章地址:https://www.cnblogs.com/xiaxiaolu/p/10309064.html
虽然这个文章的评论中也提到了升级数据库版本可以解决,但是?甲方那边升级数据库肯定不现实的,那只好考虑换个组件什么的?我也尝试了EFCore依赖的包Microsoft.Data.SqlClient也是不行,所以这个时候就咨询其他部门(java)那边连接正常不?他们回复没有问题,然后就产生了要不再搞个java服务去连接的念头???这多尴尬,连接微软家的数据库还需要去麻烦其他语言???
领导说再找找资料 。。。然后就找到了Microsoft ODBC Driver for SQL Server
开始操作
在Nuget上搜索odbc,排名第一个的一个包是微软和dotnetframework维护的,最近一次更新在几天前,还是8.0.0版本怪新,那就根据文档去操作吧,这里需要注意的是使用ODBC去操作数据库是需要手动安装驱动的,比如我本地调试需要去下载驱动安装
下面来演示一个连接的小示例,新建一个控制台项目名字叫做MsSqlNetCoreOdbc(这里我直接创建.Net6的控制台项目),然后安装nuget包
<ItemGroup>
<PackageReference Include="System.Data.Odbc" Version="6.0.1" />
</ItemGroup>
编写如下代码
using System.Data.Odbc;
try
{
var str = "Server=xxxx;Database=dbName;Uid=sa;Pwd=123xxxx;Encrypt=no;driver=ODBC Driver 18 for SQL Server";
await using var connection = new OdbcConnection(str);
connection.Open();
string sqlQuery = "Select @@version";
var command = new OdbcCommand(sqlQuery, connection);
var reader = command.ExecuteScalar();
Console.WriteLine(reader.ToString());
Console.WriteLine("conn success");
Console.WriteLine("over");
}
catch (Exception ex)
{
Console.WriteLine($"message:{ex.Message} stackTrace:{ex.StackTrace}");
}
Console.ReadLine();
这里光看这个示例的话,和之前使用System.Data.SqlClient的改动确实不大,换了一个包,使用OdbcConnection创建DbConnection(需要注意的是如果你要使用到参数化等就需要注意了,它的参数化不是@key,而是?key? 我