none
Соединение с БД в EF 4.2, EF4.3 RRS feed

  • Вопрос

  • Обновился до EF 4.2, затем попробывал на EF 4.3.

    После обновления перестала создавать БД методом Create()

    Ниже объявление контекста:

    public partial class Entities : DbContext
    { 
            public Entities(string provider, string filePath): base(provider)
            {            
                    var str = Database.Connection.ConnectionString;
                    Database.Connection.ConnectionString = String.Format(str, filePath);
            }
    }

    Передаю имя провайдера (он ищет его в app.config)

     

    <connectionStrings>        
            <add name="SQLProvider" connectionString="Data Source=.\SQLEXPRESS;Initial catalog={0};attachdbfilename={0};Integrated Security=True;Connect Timeout=30;User Instance=False;MultipleActiveResultSets=True"
                providerName="System.Data.SqlClient" />
    </connectionStrings>
    

     

    Как видно подразумевается, что я буду передавать путь к файлу БД при создании контекста.

    После создания контекста если вызвать метод Create(); или сделать запрос к существующей БД, он выкидывает ошибку что не может найти путь {0}, хотя в конструкторе ConnectionString - путь подменяется, но он упорно продолжает искать БД по первоначальной строке.

    Если к примеру убрать из app.config  Initial catalog={0};attachdbfilename={0}; и задавать их в конструкторе - тогда файл БД создается в папке SQL сервера, а не там где я ему указал. Подскажите пожалуйста в чём может быть проблема.




    • Изменено Colifari 25 января 2012 г. 9:36
    25 января 2012 г. 9:34

Ответы

  • > Как тогда передать Provider?


    провайдер указывать не обязательно. можно передать DbConnection. например для работы с sql server compact
    пишем:
    var ssce = new TestStore(new SqlCeConnection(@"Data Source=C:\Temp\Test.sdf"));
    
    ...
    class TestStore : DbContext
    {
     public TestStore(DbConnection c) : base(c, true) { }
     public DbSet<Test> Tests { get; set; }
    }
    
    
       
           
    • Изменено Malobukv 25 января 2012 г. 12:39
    • Помечено в качестве ответа Colifari 25 января 2012 г. 13:36
    25 января 2012 г. 12:38

Все ответы

  • > public partial class Entities : DbContext { public Entities(string provider, string filePath): base(provider) ...


    в наследнике DbContext можно не указывать конструктор.
    см. здесь (второй пример для DbContext)
     
     

    25 января 2012 г. 11:51
  • Как тогда передать Provider?

    Если вызвать такой конструктор с передачей готового connectionString - создаёт файл в каталоге SQL сервера.

     public Entities(string connString)
            {
                    Database.Connection.ConnectionString = connString;
            }


     

    • Изменено Colifari 25 января 2012 г. 12:34
    25 января 2012 г. 12:26
  • > Как тогда передать Provider?


    провайдер указывать не обязательно. можно передать DbConnection. например для работы с sql server compact
    пишем:
    var ssce = new TestStore(new SqlCeConnection(@"Data Source=C:\Temp\Test.sdf"));
    
    ...
    class TestStore : DbContext
    {
     public TestStore(DbConnection c) : base(c, true) { }
     public DbSet<Test> Tests { get; set; }
    }
    
    
       
           
    • Изменено Malobukv 25 января 2012 г. 12:39
    • Помечено в качестве ответа Colifari 25 января 2012 г. 13:36
    25 января 2012 г. 12:38
  • Спасибо! Работает с двумя провайдерами.

    Не понятно правда в чём разница и почему он так себя ведёт если вызывать конструктор родителя с передачей параметра из app.config. И жаль что нигде не описано данное поведение и отличие в использовании конструкторов.

    25 января 2012 г. 13:36
  • > Не понятно правда в чём разница и почему он так себя ведёт если вызывать конструктор родителя с передачей параметра из app.config.


    строку соединения можно указать в app.config
    (указываем полностью, без каких либо {0})

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    	<connectionStrings>
    		<add name="cs" connectionString="Data Source=.\SQLEXPRESS;attachdbfilename=Test.mdb;Integrated Security=True;Connect Timeout=30;User Instance=False;MultipleActiveResultSets=True"			 providerName="System.Data.SqlClient" />
    	        ...
    

    для использования "cs" в коде пишем:

    var d = new Data("cs");
    
    ... 
    public class Data : DbContext
    {
        public Data(string con)
            : base(con)
        {
        }
        ...
    
      
     
    25 января 2012 г. 14:03
  • Базу необходимо выбирать в рантайме
    26 января 2012 г. 5:18
  • > Базу необходимо выбирать в рантайме


    в такой ситуации .config не подходит.
    надо создавать необходимый DbConnection и передавать его в DbContext
     
     
    26 января 2012 г. 5:29
  • Можно также брать из .config строку вида

    "Data Source=.\SQLEXPRESS;Initial catalog={0};attachdbfilename={0};Integrated Security=True;Connect Timeout=30;User Instance=False;MultipleActiveResultSets=True" 

     для нужного провайдера, форматировать ее в рантайме как нужно и создавать из нее DbConnection.


    Для связи [mail]
    26 января 2012 г. 6:39
  • так и сделал
    26 января 2012 г. 9:18