在 Blazor .net 核心应用程序中查找连接字符串时出错

Posted

技术标签:

【中文标题】在 Blazor .net 核心应用程序中查找连接字符串时出错【英文标题】:Error finding connection string in Blazor .net core app 【发布时间】:2021-01-21 17:27:14 【问题描述】:

我有一个带有 EF Core 5 的 .netcore 3.1 blazor 应用程序,并且在使用 Scaffold-DbContext "Name=MyDb" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Context MyDb_Context -Force

如果我使用,一切正常 Scaffold-DbContext "Server=servername;Database=MyDb;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Context MyDb_Context -Force 但我想避免在源代码中包含连接字符串。

一切都正确,但是,当我尝试将数据显示到列表时,会出现以下错误: System.InvalidOperationException: A named connection string was used, but the name 'MyDb' was not found in the application's configuration. Note that named connection strings are only supported when using 'IConfiguration' and a service provider, such as in a typical ASP.NET Core application. See https://go.microsoft.com/fwlink/?linkid=850912 for more information.

下面是我的 appsettings.json 的代码:


"ConnectionStrings": 
    "MyDb": "Server=servername;Database=MyDb;Integrated Security=True"
  

这是我的 MyDb_Context:

    public partial class MyDb_Context : DbContext
    
        public MyDb_Context()
        
        

        public MyDb_Context(DbContextOptions<MyDb_Context> options)
            : base(options)
        
        

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        
            if (!optionsBuilder.IsConfigured)
            
                optionsBuilder.UseSqlServer("Name=MyDb");
            
        
...

这是我的 Startup.cs:

    public class Startup
    
        public Startup(IConfiguration configuration, IWebHostEnvironment env)
        
            Configuration = configuration;
            _env = env;
        

        private readonly IWebHostEnvironment _env;
        public IConfiguration Configuration  get; 

        public void ConfigureServices(IServiceCollection services)
        
            var connection = Configuration.GetConnectionString("MyDb");
            services.AddDbContext<MyDb_Context>(options => options.UseSqlServer(connection));
        
...

这是我的服务中调用的内容:

 public class MyDbService
    
        public readonly MyDb_Context mydb_context;

        public MyDbService(MyDb_Context mydbctx)
        
            MyDb_Context = mydbctx;
            MyDb_Context.Database.SetCommandTimeout(60);
        

        public Task<List<MyDbTableName>> GetMyDbContent()
        
            var usernames = mydb_context.usernames.Where(u => u.AppId == 2).ToListAsync();

            return usernames ;
        
...


然后在我的 Razor 页面中,我使用以下代码:

@code
       private List<usernames> _usernames;

       
       MyDbService mydbservice = new MyDbService(new MyDb_Context()); //I think this line is where it is breaking

       protected override async Task OnInitializedAsync()
        
            //Grab function from the service listed above
            //Function:
            _usernames = await mydbservice.GetMyDbContent();
        


我不知道为什么它找不到连接字符串,我什至可以在 startup.cs 上放一个断点 optionsBuilder.UseSqlServer("Name=MyDb"); 可以很好的读取连接字符串。

我还可以看到在尝试时加载了 DBContext services.toList(); 和断点就可以了。

请帮忙,我已经做了一个多星期了,已经用尽了我的努力。

【问题讨论】:

Startup服务中注册服务MyDbService。你能显示使用 MyDbService 的代码吗? 你能显示DbContext在哪里注册在容器中吗? 我应该注意,使用“Server=servername;Database=MyDb;Trusted_Connection=True;”时MyDb_Context.cs 中的硬编码连接字符串,一切正常。我想使用 '"Name=MyDb" 来避免在源代码中包含连接字符串。我已更新我的问题以包含此信息,我深表歉意 【参考方案1】:Startup 类中注册服务MyDbService 以便稍后由DI 注入:
public void ConfigureServices(IServiceCollection services)
        
            //...other services            
            services.AddScoped<MyDbService>();
        
将服务注入到组件中
@* inject the service *@
@inject MyDbService mydbservice
 
//....

@code
    private List<usernames> _usernames;

//DO NOT instianate the service, it's injected 
   // MyDbService mydbservice = new MyDbService(new MyDb_Context()); //I think this line is where it is breaking

    protected override async Task OnInitializedAsync()
    
        //Grab function from the service listed above
        //Function:
        _usernames = await mydbservice.GetMyDbContent(); //now it's working
    


修改MyDbService的Constructor中的下一行:
  // MyDb_Context = mydbctx; //invalid
  mydb_context = mydbctx;

Scaffold-DbContext 使用命名连接是有效的,因为我们使用的是 DI。

Scaffold-DbContext "Name=MyDb" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Context MyDb_Context -Force

我测试了这个解决方案,它工作正常。

【讨论】:

有效!是的,谢谢!我应该知道它找不到上下文,因为它启动了一个新上下文。你碰巧知道是否有这方面的文件吗?我找不到任何涉及 razer 组件的东西。【参考方案2】:

我怀疑Scaffold-DbContext 命令有问题。我认为您应该提供完整的连接字符串,如下所示:

Scaffold-DbContext "Server=servername;Database=MyDb;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Context MyDb_Context -Force

【讨论】:

通过使用 Name=MyDb,我可以避免在源代码中出现连接字符串,这是我想要实现的。【参考方案3】:

在您的 MyDb_Context 页面中,我没有看到 puplic dbset&lt;MyModel&gt; Object get; set; ,您需要它来查询和保存模型的实例!

【讨论】:

您好,我的上下文文件中的每个表都有公共 DbSet,为了这个公共问题,我已经删除了内容

以上是关于在 Blazor .net 核心应用程序中查找连接字符串时出错的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Blazor Web 程序集中检查客户端连接状态

ASP.NET 核心 blazor webassembly 为 Identity Server 4 Postman 测试获取令牌

.net Core 的实体框架 6。在 Blazor 服务器端

ConvertEmptyStringToNull 不起作用 .net 核心 Blazor 项目

没有 Web 程序集的 blazor

Blazor——Asp.net core的新前端框架