locked
EF 4.2, Failed to Initialize. I restricted the problem. Please take a look ... Thank You. RRS feed

  • Question

  •  

    Hello,

    I am working with EF 4.2 and I want to create a database from a SQL Script.

    I implemented an IDatabaseInitializer and I want to run it manually from a Test method:

    Context context = new Context()
    Database.SetInitializer<Context>(new ContextInitializer());
    context.Database.Initialize(true);
    

    On the Database Initializer I am following the steps:

    1 - Check if database exists and if it is not compatible.

         If true then delete database and set exists=false;

    2 - If the database does not exist then:

         Use master to run the script that creates the database;

         Use new context to run the script that creates the database tables.

        public void InitializeDatabase(Context context) {
    
          // Does the database exist and is not compatible?
          Boolean exists = false;
          using (Context newContext = new Context()) {
            exists = newContext.Database.Exists();       
            if (exists) {
              if (!newContext.Database.CompatibleWithModel(true)) {
                newContext.Database.Delete();
                exists = false;
              }
            }
          }
    
          // And if does not exist ...
          if (!exists) {
    
            SqlConnectionStringBuilder connection = new SqlConnectionStringBuilder(context.Database.Connection.ConnectionString);
            connection.InitialCatalog = "master";
    
            // Use master to run the script that creates the database
            using (DbContext master = new DbContext(connection.ConnectionString)) {
    
              using (StreamReader deploy = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Test.Deploy.sql"))) {
                 master.Database.ExecuteSqlCommand(deploy.ReadToEnd());
              }
    
            }
           
            // Use context to run the script that creates the tables
            using (Context newContext2 = new Context()) {
    
              using (StreamReader setup = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Test.Setup.sql"))) {
    newContext2.Database.ExecuteSqlCommand(setup.ReadToEnd()); } // Update hash newContext2.Set<EdmMetadata>().Add(new EdmMetadata() { ModelHash = EdmMetadata.TryGetModelHash(newContext2) }); newContext2.SaveChanges(); } } } // InitializeDatabase } // ContextInitializer


    Finally my Deploy SQL script is simply:

     

    create database [EFDB] on primary ( 
      name = 'EFDB',
      size = 40MB,
      maxsize = 2GB,
      filegrowth = 20MB 
    ),
    filegroup [STORAGE] contains filestream ( 
      name = 'EFDB_Storage'
    )
    log on ( 
      name = 'EFDB_Log',
      size = 4MB,
      maxsize = 200MB,
      filegrowth = 2MB 
    );
    

     

     

    And the Setup SQL script is simply (I am using just this table for testing):

     

    create table dbo.EdmMetadata 
    (
      Id int identity not null,
        constraint EdmMetadata_Id_PK primary key clustered (Id),
      ModelHash nvarchar (max) null
    );
    

     


    The first time I run the test I get the error "The underlying provider failed on Open." on code line:

    newContext2.Database.ExecuteSqlCommand(setup.ReadToEnd());
    

    Note: The database was created.

    The second time I try to run it I get the following error:

      Model compatibility cannot be checked because the database does not contain model metadata. Ensure that IncludeMetadataConvention has been added to the DbModelBuilder conventions.

     

    I have been trying many options but I keep getting problems.

    Could someone please help me out?

    I can't see what I am doing wrong.

    Thank you,

    Miguel



    • Edited by MDMoura Friday, November 4, 2011 6:44 PM
    Friday, November 4, 2011 3:30 PM

All replies

  • I tried to identify the problem so I placed the following code directly on my test method:

     

          Context context = new Context();
    
          if (context.Database.Exists())
            context.Database.Delete();
    
          SqlConnectionStringBuilder connection = new SqlConnectionStringBuilder(context.Database.Connection.ConnectionString);
          connection.InitialCatalog = "master";
    
          using (DbContext master = new DbContext(connection.ConnectionString)) {
    
            using (StreamReader deploy = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Test.Deploy.sql"))) {
              master.Database.ExecuteSqlCommand(deploy.ReadToEnd());
            }
    
          }
    
          using (Context seeder = new Context()) {
    
            using (StreamReader setup = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Test.Setup.sql"))) {
              seeder.Database.ExecuteSqlCommand(setup.ReadToEnd());
            }
    
          }
    

     

    When the database exists the following happens:

    1 - The database is deleted in "context.Database.Delete();"

    2 - The database is recreated in "master.Database.ExecuteSqlCommand(deploy.ReadToEnd());"

    3 - I get the error "The underlying provider failed on Open" in "seeder.Database.ExecuteSqlCommand(setup.ReadToEnd());"

     

    Then I run it again (the database already exists because of (2)) and now everything works fine.

    Any idea why this happens and how to fix it?

    Or at least something for me to try.

    Thank You,

    Miguel

     

    Friday, November 4, 2011 6:42 PM
  • Hi Miguel,

    using (Context seeder = new Context(connection.ConnectionString)) {
    
            using (StreamReader setup = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Test.Setup.sql"))) {
              seeder.Database.ExecuteSqlCommand(setup.ReadToEnd());
            }
    

    Try to add the connectionstring here then test your code.

    Why do you want to write the method by yourself, I think you can try to use "context.Database.CreateIfNotExists()" method.

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    • Edited by Alan_chen Monday, November 7, 2011 8:18 AM
    Monday, November 7, 2011 6:53 AM
  • Try to add the connectionstring here then test your code.

    Context does not have such a constructor that takes a connection string.

    Did I miss what you were trying to say?

    Why do you want to write the method by yourself, I think you can try to use "context.Database.CreateIfNotExists()" method.

    For two reasons:

    1 - The Byte[] becomes varbinary on the database and not filestream.

    2 - I have no control over FileGroups and other configurations.

    Monday, November 7, 2011 11:24 AM