Передайте рядок підключення до першого коду DbContext


92

Як передати рядок підключення до першого коду 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 спочатку створить базу даних, якщо вона не існує ... хіба що шлях не вдається знайти, можливо ...
Стівен К.

Отже, в основному помилка OP полягала в тому, що вона надсилала весь рядок підключень до конструктора DbContaxt, а не лише до імені. Як сказано в документації: "DbContext (String) Конструює новий екземпляр контексту, використовуючи даний рядок як ім'я або рядок з'єднання для бази даних"
Göran Roseen

Відповіді:


86

Трохи пізно до гри тут, але ще один варіант:

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

2
Привіт! Це було єдине рішення, яке мене десь привело. Моя проблема полягає в тому, що я хотів би взяти налаштування з мого файлу конфігурації Azure замість web.config. Тим не менше, цей спосіб не працює, оскільки параметр 'Provider' відсутній (він встановлений як атрибут у web.config). Будь-які ідеї?
користувач

1
Відмінна відповідь! Єдиною зміною було видалення параметра connString, а потім використання рядка підключення, збереженого в налаштуваннях програми .... this.Database.Connection.ConnectionString = Properties.Settings.Default.ConnectionString
корисний Бджола

Як я можу одночасно передавати параметр як об’єкт connString, так і об’єкт DbCompiledModel?
Бехзад Ебрагімі

Приємно. Просто "це" зайве, ви можете його видалити.
Токвіль

1
якщо ваш модуль класу включає Manual changes to this file will be overwritten if the code is regenerated.в заголовок, то можна захотіти реалізувати це в частковому класі згідно з Частковими класами та методами (Керівництво з програмування на C #)
woodvi

59

Після прочитання документів я повинен передати ім’я рядка підключення:

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

Тоді, скажімо, ви створюєте рядок Sql Connection за допомогою SqlConnectioStringBuilder приблизно так:

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") { }
Elijah W. Gagne

28

У своєму DbContext створіть конструктор за замовчуванням для вашого DbContext і успадкуйте базу наступним чином:

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

1
У моєму випадку він створює БД з іменем MyConnectionString... (так рядок з'єднання існує). Я повинен поставити name=MyConnectionString.
Matthieu Charbonnier

2

Якщо ви створюєте рядок підключення в програмі, ви б використовували свою команду connString. Якщо ви використовуєте рядок підключення у веб-конфігурації. Потім ви використовуєте "ім'я" цього рядка.


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

Рядок з'єднання чудовий, шлях не повинен бути абсолютним.
Steven K.

1

При використанні моделі EF у мене є рядок підключення в кожному проекті, який використовує модель EF. Наприклад, у мене є модель EF EDMX в окремій бібліотеці класів. У мене є один рядок підключення у моєму веб-проекті (mvc), щоб він міг отримати доступ до EF db.

У мене також є інший проект модульного тестування для тестування сховищ. Для того, щоб сховища мали доступ до EF db, файл app.config тестового проекту має той самий рядок підключення.

З'єднання БД слід налаштовувати, а не кодувати, IMO.


2
Мені потрібно вручну пропустити рядок з'єднання за кодом. Я використовую ін’єкцію залежності.
Шон Маклін

1

від сюди

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

Примітка, можливо, вам доведеться додати Microsoft.EntityFrameworkCore.SqlServer


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)
{
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.