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

如何将连接字符串传递给实体框架的代码优先的 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,那么连接字符串就在那里,但是它不会创建或者查找数据库或者任何东西。

建立到 SQLServer 的连接时发生了与网络相关或实例特定的错误。找不到或无法访问服务器。验证实例名称是否正确,SQLServer 是否配置为允许远程连接。(提供程序: 命名管道提供程序,错误: 40-无法打开到 SQLServer 的连接)

226884 次浏览

Check the syntax of your connection string in the web.config. It should be something like ConnectionString="Data Source=C:\DataDictionary\NerdDinner.sdf"

When using an EF model, I have a connection string in each project that consumes the EF model. For example, I have an EF EDMX model in a separate class library. I have one connection string in my web (mvc) project so that it can access the EF db.

I also have another unit test project for testing the repositories. In order for the repositories to access the EF db, the test project's app.config file has the same connection string.

DB connections should be configured, not coded, IMO.

Can't see anything wrong with your code, I use SqlExpress and it works fine when I use a connection string in the constructor.

You have created an App_Data folder in your project, haven't you?

After reading the docs, I have to pass the name of the connection string instead:

var db = new NerdDinners("NerdDinnerDb");

If you are constructing the connection string within the app then you would use your command of connString. If you are using a connection string in the web config. Then you use the "name" of that string.

Thought I'd add this bit for people who come looking for "How to pass a connection string to a DbContext": You can construct a connection string for your underlying datastore and pass the entire connection string to the constructor of your type derived from DbContext.

(Re-using Code from @Lol Coder) Model & Context

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

Then, say you construct a Sql Connection string using the SqlConnectioStringBuilder like so:

SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(GetConnectionString());

Where the GetConnectionString method constructs the appropriate connection string and the SqlConnectionStringBuilder ensures the connection string is syntactically correct; you may then instantiate your db conetxt like so:

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

A little late to the game here, but another option is:

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

In your DbContext, create a default constructor for your DbContext and inherit the base like this:

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

I have a little solution example for that problem.

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

For anyone who came here trying find out how to set connection string dinamicaly, and got trouble with the solutions above (like "Format of the initialization string does not conform to specification starting at index 0.") when setting up the connection string in the constructor. This is how to fix it:

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)
{
}

from here

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

note you may need to add Microsoft.EntityFrameworkCore.SqlServer