Übergeben Sie die Verbindungszeichenfolge an Code-first DbContext

90

Wie übergebe ich eine Verbindungszeichenfolge an den Code-First-DbContext des Entity Frameworks? Meine Datenbankgenerierung funktioniert ordnungsgemäß, wenn sich sowohl DbContext als auch die Verbindungszeichenfolge in web.config im selben Projekt befinden und denselben Namen haben. Aber jetzt muss ich den DbContext in ein anderes Projekt verschieben, damit ich eine Übergabe einer Verbindungszeichenfolge wie folgt teste:

Modell & Kontext

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

Aktion

    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>

Wenn ich in der Aktion einen Haltepunkt setze und die analysiere db, ist die Verbindungszeichenfolge vorhanden, aber die Datenbank oder etwas anderes wird nicht erstellt oder gefunden.

Beim Herstellen einer Verbindung zu SQL Server ist ein netzwerkbezogener oder instanzspezifischer Fehler aufgetreten. Der Server wurde nicht gefunden oder war nicht zugänglich. Stellen Sie sicher, dass der Instanzname korrekt ist und dass SQL Server so konfiguriert ist, dass Remoteverbindungen zugelassen werden. (Anbieter: Named Pipes Provider, Fehler: 40 - Verbindung zu SQL Server konnte nicht hergestellt werden)

Shawn Mclean
quelle
Sind Sie absolut sicher, dass Sie eine Verbindung zum richtigen Server herstellen? Der Fehler ist eine typische SQL Server / Express-Ausnahme. Klingt nicht so, als wären Sie mit einer SQL CE-Datenbank verbunden ... und EF Code erstellt zuerst die Datenbank, wenn sie nicht vorhanden ist ... es sei denn, der Pfad kann möglicherweise nicht gefunden werden ...
Steven K.
Im Grunde bestand der Fehler von OP darin, den gesamten Verbindungsstring an den DbContaxt-Konstruktor zu senden, anstatt nur den Namen. In den Dokumentationen heißt es: "DbContext (String) Erstellt eine neue Kontextinstanz unter Verwendung der angegebenen Zeichenfolge als Name oder Verbindungszeichenfolge für die Datenbank"
Göran Roseen

Antworten:

85

Ein bisschen spät zum Spiel hier, aber eine andere Option ist:

public class NerdDinners : DbContext
{
    public NerdDinners(string connString)
    {
        this.Database.Connection.ConnectionString = connString;
    }
    public DbSet<Dinner> Dinners { get; set; }
}
Bitfiddler
quelle
2
Hallo! Dies war die einzige Lösung, die mich irgendwohin brachte. Mein Problem ist, dass ich die Einstellungen aus meiner Azure-Konfigurationsdatei anstelle von web.config übernehmen möchte. Diese Methode funktioniert jedoch nicht, da die Einstellung "Provider" fehlt (sie wird in der web.config als Attribut festgelegt). Irgendwelche Ideen?
Benutzer
1
Hervorragende Antwort! Die einzige Änderung war connString Parameter zu entfernen, und dann die Verbindungszeichenfolge in den Anwendungseinstellungen gespeichert verwenden .... this.Database.Connection.ConnectionString = Properties.Settings.Default.ConnectionString
usefulBee
Wie kann ich sowohl das connString- als auch das DbCompiledModel-Objekt gleichzeitig mit dem Parameter übergeben?
Behzad Ebrahimi
Nett. Nur "dies" ist redundant, Sie können es entfernen.
Tocqueville
1
Wenn Ihr Klassenmodul Manual changes to this file will be overwritten if the code is regenerated.in der Kopfzeile enthalten ist, möchten Sie dies möglicherweise in einer
Teilklasse gemäß Teilklassen
58

Nach dem Lesen der Dokumente muss ich stattdessen den Namen der Verbindungszeichenfolge übergeben:

var db = new NerdDinners("NerdDinnerDb");
Shawn Mclean
quelle
Ich habe das in meinen Konstruktor eingefügt und es zu einer öffentlichen Konstante gemacht, falls es an anderer Stelle als Referenz benötigt wird.
Tony Wall
37

Ich dachte, ich würde dieses Bit für Leute hinzufügen, die nach "So übergeben Sie eine Verbindungszeichenfolge an einen DbContext" suchen: Sie können eine Verbindungszeichenfolge für Ihren zugrunde liegenden Datenspeicher erstellen und die gesamte Verbindungszeichenfolge an den von DbContext abgeleiteten Konstruktor Ihres Typs übergeben .

(Wiederverwendung von Code aus @Lol Coder) Modell & Kontext

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

Angenommen, Sie erstellen eine SQL-Verbindungszeichenfolge mit dem SqlConnectioStringBuilder wie folgt:

SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(GetConnectionString());

Wenn die GetConnectionString-Methode die entsprechende Verbindungszeichenfolge erstellt und der SqlConnectionStringBuilder sicherstellt, dass die Verbindungszeichenfolge syntaktisch korrekt ist; Sie können dann Ihren Datenbankkontext wie folgt instanziieren:

var myContext = new NerdDinners(builder.ToString());
Sudhanshu Mishra
quelle
4
Um die Verbindungszeichenfolge, die ich gemacht habe, wirklich hart zu codieren:public TestAppContext() : base("Data Source=server.company.com;Initial Catalog=SomeDB;Integrated Security=True") { }
Elijah W. Gagne
28

Erstellen Sie in Ihrem DbContext einen Standardkonstruktor für Ihren DbContext und erben Sie die Basis wie folgt:

    public myDbContext()
        : base("MyConnectionString")  // connectionstring name define in your web.config
    {
    }
Kinh Pham
quelle
1
In meinem Fall wird eine Datenbank mit dem Namen MyConnectionString... erstellt (ja, die Verbindungszeichenfolge ist vorhanden). Ich muss setzen name=MyConnectionString.
Matthieu Charbonnier
2

Wenn Sie die Verbindungszeichenfolge in der App erstellen, verwenden Sie den Befehl connString. Wenn Sie eine Verbindungszeichenfolge in der Webkonfiguration verwenden. Dann verwenden Sie den "Namen" dieser Zeichenfolge.

MKunstman
quelle
2

Ich habe ein kleines Lösungsbeispiel für dieses 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);
Durgesh Pandey
quelle
1

Überprüfen Sie die Syntax Ihrer Verbindungszeichenfolge in der Datei web.config. Es sollte so etwas wie seinConnectionString="Data Source=C:\DataDictionary\NerdDinner.sdf"

kmerkle
quelle
Die Verbindungszeichenfolge funktioniert, wenn beide im selben Projekt denselben Namen verwenden.
Shawn Mclean
Es funktioniert nicht, wenn ich es manuell an den DbConext übergeben möchte
Shawn Mclean
Die Verbindungszeichenfolge ist in Ordnung, der Pfad muss nicht absolut sein.
Steven K.
1

Bei Verwendung eines EF-Modells habe ich in jedem Projekt eine Verbindungszeichenfolge, die das EF-Modell verwendet. Zum Beispiel habe ich ein EF EDMX-Modell in einer separaten Klassenbibliothek. Ich habe eine Verbindungszeichenfolge in meinem Webprojekt (mvc), damit es auf die EF-Datenbank zugreifen kann.

Ich habe auch ein anderes Unit-Test-Projekt zum Testen der Repositories. Damit die Repositorys auf die EF-Datenbank zugreifen können, hat die Datei app.config des Testprojekts dieselbe Verbindungszeichenfolge.

DB-Verbindungen sollten konfiguriert, nicht codiert, IMO.

danludwig
quelle
2
Ich muss die Verbindungszeichenfolge manuell per Code übergeben. Ich verwende die Abhängigkeitsinjektion.
Shawn Mclean
0

Ich kann SqlExpress nicht verwenden und es funktioniert einwandfrei, wenn ich eine Verbindungszeichenfolge im Konstruktor verwende.

Sie haben in Ihrem Projekt einen App_Data-Ordner erstellt, oder?

Lee Smith
quelle
0

Für alle, die hierher gekommen sind und versucht haben, herauszufinden, wie die Verbindungszeichenfolge dinamisch eingestellt werden kann, und Probleme mit den oben genannten Lösungen (wie "Format der Initialisierungszeichenfolge entspricht nicht der Spezifikation ab Index 0") beim Einrichten der Verbindungszeichenfolge in der Konstrukteur. So beheben Sie das Problem:

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)
{
}
Thiago Araujo
quelle
0

von hier

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

Beachten Sie, dass Sie möglicherweise hinzufügen müssen Microsoft.EntityFrameworkCore.SqlServer

Abdullah Tahan
quelle