Передать строку подключения в 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) Создает новый экземпляр контекста, используя данную строку в качестве имени или строки подключения для базы данных»
Йоран Розен

Ответы:

86

Немного поздно к игре, но другой вариант:

public class NerdDinners : DbContext
{
    public NerdDinners(string connString)
    {
        this.Database.Connection.ConnectionString = connString;
    }
    public DbSet<Dinner> Dinners { get; set; }
}
Bitfiddler
источник
2
Здравствуй! Это было единственное решение, которое меня куда-то привело. Моя проблема в том, что я хотел бы взять настройки из моего файла конфигурации Azure вместо web.config. Тем не менее, этот способ не работает, поскольку параметр «Поставщик» отсутствует (он установлен как атрибут в файле web.config). Любые идеи?
пользователь
1
Отличный ответ! Единственное внесенное изменение заключалось в удалении параметра connString и последующем использовании строки подключения, сохраненной в настройках приложения .... this.Database.Connection.ConnectionString = Properties.Settings.Default.ConnectionString
полезноBee
Как я могу передать объект connString и DbCompiledModel одновременно в качестве параметра?
Behzad Ebrahimi
Ницца. Просто «это» лишнее, убрать можно.
tocqueville 07
1
если ваш модуль класса включен Manual changes to this file will be overwritten if the code is regenerated.в заголовок, то можно захотеть реализовать это в частичном классе в соответствии с частичными классами и методами (Руководство по программированию на C #)
woodvi
59

После прочтения документации я должен вместо этого передать имя строки подключения:

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

Затем предположим, что вы создаете строку подключения Sql с помощью 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") { }
Элайджа В. Гань
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"

Kmerkle
источник
Строка подключения работает, когда они оба используют одно и то же имя в одном проекте.
Шон Маклин
Это не работает, когда я хочу вручную передать его в DbConext
Шон Маклин
Строка подключения в порядке, путь не обязательно должен быть абсолютным.
Стивен К.
1

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

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

Соединения с БД должны быть настроены, а не закодированы, ИМО.

данлудвиг
источник
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)
{
}
Тьяго Араухо
источник