我有一个运行有SQL数据库的Net.Core应用程序。连接字符串在环境变量中。
在本地IIS上,应用程序运行正常。
与Docker-Container相同的应用程序出现以下错误
失败:Microsoft.AspNetCore.Server.Kestrel [13] 连接ID“ 0HLPO85V83VNO”,请求ID“ 0HLPO85V83VNO:00000001”:客户端抛出未处理的异常 应用。 System.PlatformNotSupportedException:不是LocalDB 在此平台上受支持。
在 System.Data.SqlClient.SNI.LocalDB.GetLocalDBConnectionString(String localDbInstance)
在 System.Data.SqlClient.SNI.SNIProxy.GetLocalDBDataSource(字符串 fullServerName,布尔值和错误)
Docker的环境变量: “ DB_CONNECTION”:“服务器= hc-XXX;数据库= IB33DB-Core_XXX;用户ID = sa;密码= XXX”
这是网络中的设置
Startup.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using ib.api_core.Data;
using Microsoft.EntityFrameworkCore;
using ib.api_core.Models;
namespace ib.api_core
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddJsonOptions(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
string dbConnection = Environment.GetEnvironmentVariable("DB_CONNECTION");
Console.WriteLine("Env var DB Connection: "+dbConnection);
//Verweis auf den Datenbank Kontext
services.AddDbContext<ibContext>(options =>
options.UseSqlServer(dbConnection));
//Verweis auf den Datenbank Kontext
// services.AddDbContext<ibContext>(options =>
// options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
//1. Alle Anfragen in der Konsole loggen
app.UseMiddleware<RequestResponseLoggingMiddleware>();
//2. Prüfe Login und Berechtigung der Anfrage
app.UseMiddleware<AuthenticationMiddleware>();
app.UseHttpsRedirection();
app.UseMvc();
}
}
}
ibContext.cs
using System;
using Microsoft.EntityFrameworkCore;
namespace ib.api_core.Models
{
public partial class ibContext : DbContext
{
public ibContext()
{
}
public ibContext(DbContextOptions<ibContext> options)
: base(options)
{
}
public static ibContext GetContext()
{
var optionsBuilder = new DbContextOptionsBuilder<ibContext>();
optionsBuilder.UseSqlServer(Environment.GetEnvironmentVariable("DB_CONNECTION"));
return new ibContext(optionsBuilder.Options);
}
[...]
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer(Environment.GetEnvironmentVariable("DB_CONNECTION"));
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
....
答案 0 :(得分:1)
该错误消息表示在某些时候,您的代码尝试使用为LocalDB配置的连接字符串来访问数据库。我怀疑在您的appsettings.json中,有一个使用LocalDB的连接字符串,该连接字符串有时会被使用。
从代码示例中,我无法找出原因。也许某些代码绕过了环境变量,并从配置文件中读取了连接字符串,或者容器运行了旧版本的代码。
但是,在基于此sample的项目中,我能够覆盖容器中的连接字符串:
以下代码使用.NET Core configuration获取连接字符串。这种方法的优点是,您可以通过多种方式提供连接字符串,并且在运行容器时也可以覆盖它。
示例中使用的上下文很简单:
public class BloggingContext : DbContext
{
public BloggingContext(DbContextOptions<BloggingContext> options)
: base(options)
{ }
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
}
在 startup.cs 中,使用.NET Core配置注册上下文并检索连接字符串:
var connection = Configuration.GetConnectionString("DefaultConnection");
services.AddDbContext<BloggingContext>
(options => options.UseSqlServer(connection));
对于开发,使用在 appsettings.json 中配置的LocalDB:
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=EFGetStarted.AspNetCore.NewDb;Trusted_Connection=True;ConnectRetryCount=0"
}
}
运行容器时,名为ConnectionStrings:DefaultConnection
的环境变量将覆盖来自appsettings文件的连接字符串。
为进行调试,我在 launchsettings.json 中插入了一个环境变量:
...
"Docker": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
"environmentVariables": {
"ASPNETCORE_URLS": "https://+:443;http://+:80",
"ASPNETCORE_HTTPS_PORT": "44330",
"ConnectionStrings:DefaultConnection": "Data Source=MY_IP\\MY_INSTANCE;Initial Catalog=TestDb;User Id=MY_USER;Password=MY_PWD"
},
"httpPort": 10000,
"useSSL": true,
"sslPort": 44330
}
...
在IIS Express中运行时,将使用 appsettings.json 中的连接字符串,在容器中运行时,将按照环境变量中的配置访问主机上的SQL Server实例。
答案 1 :(得分:1)
太晚了。但也许它会帮助面临这个问题的人。
您可以在 ConnectionString 中使用 host.docker.internal ,它将解析为您的主机 IP。 例如(1433 - sqlServer 使用的端口) "Server=host.docker.internal,1433;Database=yourDatabaseName;Integrated Security=False;MultipleActiveResultSets=true;User=DbUser;Password=DbPassword;"