将连接字符串传递给代码优先的 DbContext

Posted

技术标签:

【中文标题】将连接字符串传递给代码优先的 DbContext【英文标题】:Pass connection string to code-first DbContext 【发布时间】:2011-06-15 20:39:47 【问题描述】:

如何将连接字符串传递给实体框架的代码优先 DbContext?当 DbContext 和 web.config 中的连接字符串在同一个项目中并且以相同的方式命名时,我的数据库生成工作正常。但是现在我需要将 DbContext 移动到另一个项目,所以我正在测试将连接字符串传递给它,如下所示:

模型和上下文

public class Dinner

    public int DinnerId  get; set; 
    public string Title  get; set; 


public class NerdDinners : DbContext

    public NerdDinners(string connString)
        : base(connString)
    
    
    public DbSet<Dinner> Dinners  get; set; 

动作

    public ActionResult Index()
    
        var db = new NerdDinners(ConfigurationManager.ConnectionStrings["NerdDinnerDb"].ConnectionString);

        var dinners = (from d in db.Dinners
                      select d).ToList();
        return View(dinners);
    

Web.Config

<connectionStrings>
  <add name="NerdDinnerDb" connectionString="Data Source=|DataDirectory|NerdDinners.sdf" providerName="System.Data.SqlServerCe.4.0"/>    
</connectionStrings>

如果我在分析db 的操作中设置断点,则连接字符串在那里,但它不会创建或查找数据库或任何东西。

与 SQL Server 建立连接时出现与网络相关或特定于实例的错误。服务器未找到或无法访问。验证实例名称是否正确以及 SQL Server 是否配置为允许远程连接。 (提供者:命名管道提供者,错误:40 - 无法打开与 SQL Server 的连接)

【问题讨论】:

您确定连接到正确的服务器吗?该错误是典型的 SQL Server/Express 异常。听起来您不像是连接到 Sql CE 数据库...如果数据库不存在,EF 代码将首先创建数据库...除非可能找不到路径... 所以基本上,OP 的错误是将整个连接字符串发送到 DbContaxt 构造函数,而不仅仅是名称。正如文档所说:“DbContext(String) 使用给定的字符串作为数据库的名称或连接字符串构造一个新的上下文实例” 【参考方案1】:

这里的游戏有点晚了,但另一种选择是:

public class NerdDinners : DbContext

    public NerdDinners(string connString)
    
        this.Database.Connection.ConnectionString = connString;
    
    public DbSet<Dinner> Dinners  get; set; 

【讨论】:

嗨!这是让我到达某个地方的唯一解决方案。我的问题是我想从我的 Azure 配置文件而不是 web.config 中获取设置。尽管如此,这种方式仍然不起作用,因为缺少“提供者”设置(它被设置为 web.config 中的属性)。有什么想法吗? 优秀的答案!所做的唯一更改是删除 connString 参数,然后使用保存在应用程序设置中的连接字符串.... this.Database.Connection.ConnectionString = Properties.Settings.Default.ConnectionString 如何同时传递 connString 和 DbCompiledModel 对象作为参数? 不错。只是“this”是多余的,可以去掉。 如果您的类模块在标头中包含Manual changes to this file will be overwritten if the code is regenerated.,那么可能希望按照Partial Classes and Methods (C# Programming Guide)在部分类中实现这一点【参考方案2】:

阅读文档后,我必须改为传递连接字符串的名称:

var db = new NerdDinners("NerdDinnerDb");

【讨论】:

我把它放在我的构造函数中,并把它作为一个公共常量,以防需要在其他地方引用。【参考方案3】:

我想为那些寻找“如何将连接字符串传递给 DbContext”的人添加这一点:您可以为底层数据存储构造一个连接字符串,并将整个连接字符串传递给您类型的构造函数派生自 DbContext。

(重用来自@Lol Coder 的代码) 模型和上下文

public class Dinner

    public int DinnerId  get; set; 
    public string Title  get; set; 


public class NerdDinners : DbContext

    public NerdDinners(string connString)
        : base(connString)
    
    
    public DbSet<Dinner> Dinners  get; set; 

然后,假设您使用 SqlConnectiostringBuilder 构造一个 Sql Connection 字符串,如下所示:

SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(GetConnectionString());

GetConnectionString 方法构造适当的连接字符串,而 SqlConnectionStringBuilder 确保连接字符串在语法上是正确的;然后你可以像这样实例化你的 db conetxt:

var myContext = new NerdDinners(builder.ToString());

【讨论】:

对我所做的连接字符串进行真正的硬编码:public TestAppContext() : base("Data Source=server.company.com;Initial Catalog=SomeDB;Integrated Security=True") 【参考方案4】:

在您的 DbContext 中,为您的 DbContext 创建一个默认构造函数并像这样继承基础:

    public myDbContext()
        : base("MyConnectionString")  // connectionstring name define in your web.config
    
    

【讨论】:

在我的例子中,它创建了一个名为 MyConnectionString... 的数据库(是的,连接字符串存在)。我必须输入name=MyConnectionString【参考方案5】:

我有一个解决这个问题的小例子。

MyDBContext.cs

 public MyDBContext(DBConnectionType ConnectionType) //: base("ConnMain")
  
      if(ConnectionType==DBConnectionType.MainConnection)
       
         this.Database.Connection.ConnectionString = ConfigurationManager.ConnectionStrings["ConnMain"].ConnectionString;
       
      else if(ConnectionType==DBConnectionType.BackupConnection)
       
         this.Database.Connection.ConnectionString = ConfigurationManager.ConnectionStrings["ConnBackup"].ConnectionString;
       
  

MyClass.cs

public enum DBConnectionType
 
    MainConnection=0,
    BackupConnection=1
 

frmMyForm.cs

 MyDBContext db = new MyDBContext(DBConnectionType.MainConnection);
                               //or
//MyDBContext db = new MyDBContext(DBConnectionType.BackupConnection);

【讨论】:

【参考方案6】:

如果您在应用程序中构建连接字符串,那么您将使用 connString 命令。如果您在 Web 配置中使用连接字符串。然后使用该字符串的“名称”。

【讨论】:

【参考方案7】:

检查 web.config 中连接字符串的语法。它应该类似于ConnectionString="Data Source=C:\DataDictionary\NerdDinner.sdf"

【讨论】:

连接字符串在同一个项目中使用相同名称时有效。 当我想手动将它传递给 DbConext 时它不起作用 连接字符串可以,路径不需要是绝对的。【参考方案8】:

使用 EF 模型时,我在每个使用 EF 模型的项目中都有一个连接字符串。例如,我在一个单独的类库中有一个 EF EDMX 模型。我的 web (mvc) 项目中有一个连接字符串,以便它可以访问 EF db。

我还有另一个用于测试存储库的单元测试项目。为了使存储库能够访问 EF db,测试项目的 app.config 文件具有相同的连接字符串。

应该配置数据库连接,而不是编码,IMO。

【讨论】:

我需要手动通过代码传递连接字符串。我正在使用依赖注入。【参考方案9】:

来自here

 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    
      optionsBuilder.UseSqlServer(ConfigurationManager.ConnectionStrings["BloggingDatabase"].ConnectionString);
    

请注意,您可能需要添加Microsoft.EntityFrameworkCore.SqlServer

【讨论】:

【参考方案10】:

看不出你的代码有什么问题,我使用 SqlExpress,当我在构造函数中使用连接字符串时它工作正常。

您已经在项目中创建了一个 App_Data 文件夹,不是吗?

【讨论】:

【参考方案11】:

对于任何来到这里尝试了解如何设置连接字符串的人,但在设置连接时遇到了上述解决方案(例如“初始化字符串的格式不符合从索引 0 开始的规范”)。构造函数中的字符串。这是修复它的方法:

public static string ConnectionString

    get 
        if (ConfigurationManager.AppSettings["DevelopmentEnvironment"] == "true")
            return ConfigurationManager.ConnectionStrings["LocalDb"].ConnectionString;
        else
            return ConfigurationManager.ConnectionStrings["ExternalDb"].ConnectionString;
    


public ApplicationDbContext() : base(ConnectionString)


【讨论】:

以上是关于将连接字符串传递给代码优先的 DbContext的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Entity Framework Core 中将连接字符串传递给 DBContext?

有没有办法将已经打开的 MySQL 连接传递给 EF Core DbContext ?用于多线程目的

MVC 代码优先 - 数据库未生成

将 DbContextOptions<dbContext> 传递给基本上下文

实体框架代码优先 - DbContext 上没有 Detach() 方法

连接到 mongoDB