Przekaż parametry połączenia do DbContext w pierwszej kolejności


92

Jak przekazać parametry połączenia do DbContext w pierwszej kolejności kodu jednostki? Generowanie mojej bazy danych działa poprawnie, gdy zarówno DbContext, jak i parametry połączenia w pliku web.config znajdują się w tym samym projekcie i mają taką samą nazwę. Ale teraz muszę przenieść DbContext do innego projektu, więc testuję przekazanie parametrów połączenia do niego w następujący sposób:

Model i kontekst

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

Akcja

    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>

Jeśli ustawię punkt przerwania w akcji i przeanalizuję db, ciąg połączenia tam jest, ale nie tworzy ani nie znajduje bazy danych ani niczego.

Podczas nawiązywania połączenia z programem SQL Server wystąpił błąd związany z siecią lub wystąpieniem. Serwer nie został znaleziony lub nie był dostępny. Sprawdź, czy nazwa instancji jest poprawna i czy SQL Server jest skonfigurowany do zezwalania na połączenia zdalne. (dostawca: dostawca nazwanych potoków, błąd: 40 - nie można otworzyć połączenia z programem SQL Server)


Czy jesteś absolutnie pewien, że łączysz się z właściwym serwerem? Błąd jest typowym wyjątkiem programu SQL Server / Express. Nie brzmi to tak, jakbyś był połączony z bazą danych Sql CE ... a EF Code najpierw utworzy bazę danych, jeśli ona nie istnieje ... chyba że nie można znaleźć ścieżki ...
Steven K.

Zasadniczo błędem OP było wysłanie całego ciągu połączenia do konstruktora DbContaxt, a nie tylko nazwy. Zgodnie z dokumentacją: „DbContext (String) Konstruuje nową instancję kontekstu, używając podanego ciągu jako nazwy lub ciągu połączenia z bazą danych”
Göran Roseen

Odpowiedzi:


86

Trochę za późno do gry tutaj, ale inna opcja to:

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

2
Cześć! To było jedyne rozwiązanie, które gdzieś mnie doprowadziło. Mój problem polega na tym, że chciałbym pobrać ustawienia z mojego pliku konfiguracyjnego platformy Azure zamiast z pliku web.config. Mimo to ten sposób nie działa, ponieważ brakuje ustawienia „Dostawca” (jest ono ustawione jako atrybut w pliku web.config). Jakieś pomysły?
użytkownik

1
Doskonała odpowiedź! Jedyną wprowadzoną zmianą było usunięcie parametru connString, a następnie użycie parametrów połączenia zapisanych w ustawieniach aplikacji .... this.Database.Connection.ConnectionString = Properties.Settings.Default.ConnectionString
przydatneBee

Jak mogę przekazać oba obiekty connString i DbCompiledModel w tym samym czasie co parametr?
Behzad Ebrahimi

Ładny. Po prostu „to” jest zbędne, możesz je usunąć.
tocqueville

1
jeśli twój moduł klasy zawiera Manual changes to this file will be overwritten if the code is regenerated.w nagłówku, możesz chcieć zaimplementować to w częściowej klasie zgodnie z Częściowymi klasami i metodami (Przewodnik programowania C #)
woodvi

59

Po przeczytaniu dokumentacji muszę zamiast tego podać nazwę parametrów połączenia:

var db = new NerdDinners("NerdDinnerDb");

Umieściłem to w moim konstruktorze i uczyniłem publiczną stałą na wypadek, gdyby była potrzebna w innym miejscu.
Tony Wall

37

Pomyślałem, że dodam ten bit dla osób, które szukają „Jak przekazać parametry połączenia do DbContext”: Możesz utworzyć parametry połączenia dla bazowego magazynu danych i przekazać całe parametry połączenia do konstruktora Twojego typu pochodzącego z DbContext .

(Ponowne użycie kodu z @Lol Coder) Model i kontekst

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

Następnie powiedzmy, że konstruujesz ciąg połączenia Sql przy użyciu SqlConnectioStringBuilder w następujący sposób:

SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(GetConnectionString());

Gdzie metoda GetConnectionString tworzy odpowiednie parametry połączenia, a SqlConnectionStringBuilder zapewnia, że ​​parametry połączenia są poprawne pod względem składniowym; możesz następnie utworzyć instancję swojego db conetxt w następujący sposób:

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

4
Aby naprawdę mocno zakodować ciąg połączenia, zrobiłem:public TestAppContext() : base("Data Source=server.company.com;Initial Catalog=SomeDB;Integrated Security=True") { }
Elijah W. Gagne

28

W swoim DbContext utwórz domyślny konstruktor dla swojego DbContext i dziedzicz podstawę w następujący sposób:

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

1
W moim przypadku tworzy bazę danych o nazwie MyConnectionString... (tak, ciąg połączenia istnieje). Muszę położyć name=MyConnectionString.
Matthieu Charbonnier

2

Jeśli konstruujesz parametry połączenia w aplikacji, użyj polecenia connString. Jeśli używasz parametrów połączenia w pliku config. Następnie używasz „nazwy” tego ciągu.


2

Mam mały przykład rozwiązania tego problemu.

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

Sprawdź składnię parametrów połączenia w pliku web.config. To powinno być coś w rodzajuConnectionString="Data Source=C:\DataDictionary\NerdDinner.sdf"


Parametry połączenia działają, gdy oba używają tej samej nazwy w tym samym projekcie.
Shawn Mclean

Nie działa, gdy chcę ręcznie przekazać go do DbConext
Shawn Mclean

Parametry połączenia są prawidłowe, ścieżka nie musi być bezwzględna.
Steven K.

1

W przypadku korzystania z modelu EF mam parametry połączenia w każdym projekcie, który korzysta z modelu EF. Na przykład mam model EF EDMX w oddzielnej bibliotece klas. Mam jeden ciąg połączenia w moim projekcie sieci web (MVC), dzięki czemu może uzyskać dostęp do bazy danych EF.

Mam też inny projekt testów jednostkowych do testowania repozytoriów. Aby repozytoria miały dostęp do bazy danych EF, plik app.config projektu testowego ma takie same parametry połączenia.

Połączenia DB powinny być skonfigurowane, a nie kodowane, IMO.


2
Muszę ręcznie przekazać parametry połączenia według kodu. Używam zastrzyku zależności.
Shawn Mclean

1

od tutaj

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

uwaga, może być konieczne dodanie Microsoft.EntityFrameworkCore.SqlServer


0

Nie widzę nic złego w kodzie, używam SqlExpress i działa dobrze, gdy używam parametrów połączenia w konstruktorze.

Utworzyłeś folder App_Data w swoim projekcie, prawda?


0

Dla każdego, kto przyszedł tutaj, próbując dowiedzieć się, jak ustawić parametry połączenia normalnie, i miał problem z powyższymi rozwiązaniami (np. „Format ciągu inicjalizacyjnego nie jest zgodny ze specyfikacją zaczynającą się od indeksu 0”) podczas konfigurowania parametrów połączenia w konstruktor. Oto jak to naprawić:

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)
{
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.