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


90

如何将连接字符串传递给实体框架的代码优先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配置

<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 Code首先会创建数据库...除非可能找不到路径...
Steven K.

因此,基本上,OP的错误是将整个连接字符串发送给DbContaxt构造函数,而不仅仅是名称。作为本细则说:“的DbContext(字符串)使用指定的字符串作为名称或连接字符串数据库构造一个新的上下文实例”
约兰·Roseen

Answers:


85

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

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

2
嗨!这是使我进入某个位置的唯一解决方案。我的问题是我想从我的Azure配置文件而不是web.config中获取设置。不过,由于缺少“提供程序”设置(在web.config中将其设置为属性),因此这种方法仍然行不通。有任何想法吗?
用户

1
很好的答案!唯一的更改是删除connString参数,然后使用保存在应用程序设置中的连接字符串...。this.Database.Connection.ConnectionString = Properties.Settings.Default.ConnectionString
有用的

如何同时传递connString和DbCompiledModel对象作为参数?
Behzad Ebrahimi

真好 只是“ this”是多余的,您可以将其删除。
tocqueville '16

1
如果您的类模块包含Manual changes to this file will be overwritten if the code is regenerated.在头文件中,则可能需要按照部分类和方法(C#编程指南)
woodvi

58

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

var db = new NerdDinners("NerdDinnerDb");

我将其放在构造函数中,并使其成为公共常量,以备需要在其他地方引用时使用。
Tony Wall,

37

以为我会为那些正在寻找“如何将连接字符串传递到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确保连接字符串在语法上正确;然后您可以像这样实例化您的数据库锥体文本:

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

4
为了真正对连接字符串进行硬编码:public TestAppContext() : base("Data Source=server.company.com;Initial Catalog=SomeDB;Integrated Security=True") { }
Elijah W. Gagne 2013年

28

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

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

1
就我而言,它创建一个名为MyConnectionString... 的数据库(是,连接字符串存在)。我必须放name=MyConnectionString
Matthieu Charbonnier

2

如果要在应用程序内构造连接字符串,则可以使用connString命令。如果您在Web配置中使用连接字符串。然后,您使用该字符串的“名称”。


2

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

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);

1

在web.config中检查连接字符串的语法。应该是这样的ConnectionString="Data Source=C:\DataDictionary\NerdDinner.sdf"


当它们在同一项目中都使用相同的名称时,连接字符串将起作用。
肖恩·麦克林

当我想手动将其传递给DbConext时,它不起作用
Shawn Mclean

连接字符串很好,路径不必是绝对的。
史蒂文·K。

1

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

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

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


2
我需要通过代码手动传递连接字符串。我正在使用依赖注入。
肖恩·麦克林

0

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

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


0

对于任何来这里的人,尝试找出如何设置连接字符串的语法,并在设置连接字符串时遇到上述解决方案的麻烦(例如“初始化字符串的格式不符合从索引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)
{
}

0

这里

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.