接続文字列をコードファーストの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.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 Codeが最初にデータベースを作成します...
Steven K.

したがって、基本的に、OPのミスは、名前だけではなく、接続文字列全体をDbContaxtコンストラクターに送信することでした。ドキュメンテーションが言うように:「DbContext(文字列)データベースの名前または接続文字列として指定した文字列を使用して、新しいコンテキストインスタンスを構築します」
ヨーラン・Roseen

回答:


85

ここでゲームに少し遅れますが、別のオプションは次のとおりです。

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

2
こんにちは!これは私をどこかに連れて行った唯一の解決策でした。私の問題は、web.configではなくAzure構成ファイルから設定を取得することです。それでも、「プロバイダー」設定がないため、この方法は機能しません(web.configで属性として設定されています)。何か案は?
ユーザー

1
正解です。作られた唯一の変化はthis.Database.Connection.ConnectionString = Properties.Settings.Default.ConnectionString .... CONNSTRINGパラメータを削除し、アプリケーションの設定で保存された接続文字列を使用していた
usefulBee

connStringとDbCompiledModelオブジェクトの両方をパラメーターとして同時に渡すにはどうすればよいですか?
Behzad Ebrahimi

いいね。「これ」は冗長です。削除できます。
tocqueville 2016年

1
クラスモジュールがManual changes to this file will be overwritten if the code is regenerated.ヘッダーに含まれている場合、部分クラスとメソッド(C#プログラミングガイド)
woodvi

58

ドキュメントを読んだ後、代わりに接続文字列の名前を渡す必要があります:

var db = new NerdDinners("NerdDinnerDb");

それをコンストラクターに入れて、他の場所で参照する必要がある場合に備えて、それをパブリック定数にしました。
トニーウォール

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接続文字列を作成するとします。

SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(GetConnectionString());

GetConnectionStringメソッドが適切な接続文字列を作成し、SqlConnectionStringBuilderが接続文字列が構文的に正しいことを確認します。次に、次のようにdb conetxtをインスタンス化できます。

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

4
本当にハードコード私は、接続文字列に:public TestAppContext() : base("Data Source=server.company.com;Initial Catalog=SomeDB;Integrated Security=True") { }
イライジャ・W.ガニエ

28

DbContextで、DbContextのデフォルトコンストラクターを作成し、次のようにベースを継承します。

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

1
私の場合、それはMyConnectionString... という名前のDBを作成します(はい、接続文字列は存在します)。私は入れなければならない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"


接続文字列は、両方が同じプロジェクトで同じ名前を使用している場合に機能します。
Shawn Mclean

手動でDbConextに渡したいときに機能しません
Shawn Mclean

接続文字列は問題なく、パスは絶対パスである必要はありません。
スティーブンK.

1

EFモデルを使用するとき、EFモデルを使用する各プロジェクトに接続文字列があります。たとえば、別のクラスライブラリにEF EDMXモデルがあります。私のWeb(mvc)プロジェクトには1つの接続文字列があり、EF dbにアクセスできます。

リポジトリをテストするための別の単体テストプロジェクトもあります。リポジトリがEF dbにアクセスするために、テストプロジェクトのapp.configファイルには同じ接続文字列があります。

DB接続は、コード化ではなくIMOで構成する必要があります。


2
コードで接続文字列を手動で渡す必要があります。依存性注入を使用しています。
Shawn Mclean

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.