我有一个应用程序,该应用程序应使用命名实例连接到在远程服务器上运行的SQL Server。
使用IISExpress,我可以连接到SQL Server,但是从Docker(Linux容器)中,它失败-访问上下文时,它只是挂起了-没有抛出异常或错误消息。例如
var context = serviceScope.ServiceProvider.GetService<AppContext>();
context.Users.ToList();
在调试器中,它永远不会到达异常处理程序。
相反,我看到很多这样的输出:
The thread 125 has exited with code 0 (0x0).
The thread 164 has exited with code 0 (0x0).
The thread 0xa4 has exited with code 0 (0x0).
使用node.js,我甚至可以从docker连接到SQL Server,而不会出现问题。
当我使用时,我可以从Docker中的ASP.NET Core连接到与Docker在同一台机器上运行的SQL Server Developer版本。 [ipaddress或host.docker.internal] 1433-不幸的是,在远程SQL Server上,我无法配置固定端口。
连接字符串:
"Data Source=remoteIP\\WEBDB;Initial Catalog=TestDB;User ID=testuser;Password=******;"
还尝试了“集成安全性= False;”。在连接字符串中
服务器身份验证设置为混合
我也可以在没有实体框架的情况下重现它:
var conString = "Data Source=remoteIP\\WEBDB;Initial Catalog=TestDB;Integrated Security=False;User ID=testuser;Password=********";
using (SqlConnection conn = new SqlConnection(conString))
using (SqlCommand cmd = new SqlCommand("SELECT * FROM Users", conn))
{
conn.Open();
var rows = cmd.ExecuteNonQuery();
Console.WriteLine($"rows: {rows}");
}
它将挂在conn.Open();
行上。
知道我能做什么吗?
更新:
修改
这有效:
var conString = "Data Source=10.0.75.1,1433;Initial Catalog=TestDB;Integrated Security=False;User ID=testuser;Password=********";
这不起作用:
var conString = "Data Source=10.0.75.1\\Developer;Initial Catalog=TestDB;Integrated Security=False;User ID=testuser;Password=********";
我可以ping通远程IP地址以及远程服务器名称。
不幸的是,由于缺少相关性,因此在ubuntu映像上安装mssql-cli失败。
答案 0 :(得分:0)
Data Source
是错误的。命名实例仅使用单个反斜杠。正确的来源是:
remoteIP\WEBDB
仅当字符串存储在需要这种转义的媒体中(例如,在C#字符串或JSON字符串中)时,反斜杠needs to be escaped。对于C#,JSON,Javascript和与C ++相关的语言,转义字符是反斜杠本身,例如:
var connectionString="Data Source=remoteIP\\WEBDB;Initial Catalog=TestDB;User ID=testuser;Password=******;"
或
{
"ConnectionStrings": {
"BloggingDatabase": "Server=(localdb)\\mssqllocaldb;Database=EFGetStarted.ConsoleApp.NewDb;Trusted_Connection=True;"
},
}
文字C#字符串,XML或INI文件不需要转义。下面的C#行不需要转义。
var connectionString=@"Data Source=remoteIP\WEBDB;Initial Catalog=TestDB;User ID=testuser;Password=******;"
修改
固定名称只是可能出错的一件事。 DNS尝试将无法识别的字符串解析为有效IP时,错误的地址很容易将应用程序移交给应用程序。
另一个问题是,默认情况下,Docker容器具有 no 网络连接。您必须指定它们可以连接的内容以及内部IP和端口如何映射到外部IP和端口。
您可以使用SQL Server CLI工具mssql-cli来测试与服务器的连接性,而无需使用以下命令运行您自己的应用程序:
mssql-cli -S InternallyMappedIP\WEBDB -d TestDB -U testuser
答案 1 :(得分:0)
我正在使用Docker容器化应用程序。我添加了如下的连接字符串,
services.AddDbContext<OrderContext>(options =>
{
options.UseSqlServer(Configuration["ConnectionString"]);
});
我的连接字符串如下:
Server=sqlserver ; Database=CustomerDb; User Id=sa;Password=8jkGh47hnDw89Haq8LN2
sqlserver是在docker上运行的sql映像,
sqlserver:
image: microsoft/mssql-server-linux:latest
container_name: sqlserver
ports:
- "7100"
environment:
- ACCEPT_EULA=Y
- MSSQL_PID=Developer
- SA_PASSWORD=8jkGh47hnDw89Haq8LN2
答案 2 :(得分:0)
尝试在连接字符串中添加“连接超时= 60”。
答案 3 :(得分:0)
Issue #222 in SqlClient repository解释了问题。
我已经验证了这两个选项都对我有用:
将基本docker映像文件从mcr.microsoft.com/dotnet/core/aspnet:3.1.0-buster-slim
更改为mcr.microsoft.com/dotnet/core/aspnet:3.1.0-bionic
向我的docker文件添加一些步骤:
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1.0-buster-slim AS final
RUN sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /etc/ssl/openssl.cnf
RUN sed -i 's/MinProtocol = TLSv1.2/MinProtocol = TLSv1/g' /etc/ssl/openssl.cnf
RUN sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /usr/lib/ssl/openssl.cnf
RUN sed -i 's/MinProtocol = TLSv1.2/MinProtocol = TLSv1/g' /usr/lib/ssl/openssl.cnf
. . .
答案 4 :(得分:0)
我知道您已经解决了该问题。 我只是为别人添加更多。 输入
ipconfig
我们可以看到网络的IP
Ethernet adapter vEthernet (DockerNAT):
Connection-specific DNS Suffix . :
IPv4 Address. . . . . . . . . . . : 10.0.75.1
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . :
如果我们在IIS上运行该应用程序,则可以使用上述IP。
但是,如果我们在docker上运行,则应用程序无法连接到数据库。
Server=172.17.0.2;Database=VoiconCrochet;User Id=sa;Password=P@ssw0rd123;