views:

129

answers:

2

I am attempting to add Entity Framework, code first, to an MVC application that's been running with test data, using the CTP4 preview.

I am currently getting this error:

The model backing the 'SchedulerContext' context has changed since the database was created. Either manually delete/update the database, or call Database.SetInitializer with an IDatabaseInitializer instance. For example, the RecreateDatabaseIfModelChanges strategy will automatically delete and recreate the database, and optionally seed it with new data.

I do not want to generate a database at all, as I already have a database. So I tried adding the following to the SchedulerContext constructor:

Database.SetInitializer<SchedulerContext>(new CreateDatabaseOnlyIfNotExists<SchedulerContext>());

which had no effect at all -- I got the same error the next time it ran. The error seems to occur when it is executing a LINQ statement that accesses the database -- the first, I think.

Where should I put this statement, or is this statement the answer to this problem at all?

+1  A: 

Update

I simply glossed over the fact you already have a database and don't want to create another one...in that case the answer is to put this in your SchedulerContext class

protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder) {
    modelBuilder.IncludeMetadataInDatabase = false;
}

Old answer

You usually put it in the Global.asax

protected void Application_Start() {
    Database.SetInitializer<SchedulerContext>(new CreateDatabaseOnlyIfNotExists<SchedulerContext>());
}

Note that it will only be initialized on first use of the data context.

Update

public class DataContextInitializer : CreateDatabaseOnlyIfNotExists<SchedulerContext> {
    protected override void Seed(SchedulerContext context) {
    }
}

Then you modify the SetInitializer like so.

System.Data.Entity.Infrastructure.Database.SetInitializer<SchedulerContext>(new  DataContextInitializer());
BuildStarted
I tried that and it makes no difference -- I still get the error. I even tried changing the context name and the connection string (to use Windows authentication) and using "AlwaysRecreateDatabase" to see what kind of a database it would create. Well, it doesn't create one. Doesn't give me an error, just doesn't create it.
Cynthia
I've added my Initializer to the above answer to give you an idea as to how I accomplish it. This will also allow you to breakpoint and make sure it's being called.
BuildStarted
Yes!!! That did it; I can now connect to the database. Unfortunately, NOW I'm getting the following error at a certain point: "This operation requires a connection to the 'master' database. Unable to create a connection to the 'master' database because the original database connection has been opened and credentials have been removed from the connection string. Supply an unopened connection." Any ideas! (Thanks for fixing the first problem!)
Cynthia
Per a thread on MSDN forums, this is a problem MS is "working on" but has the following workaround in the Global.asax: Database.SetInitializer<SchedulerContext>(null); This prevents it from even checking for the existence of a database, so it is said. It does work.
Cynthia
Yeah, if you're not going to create a database at all there's no need for the SetInitializer so you can go ahead and remote it. Sorry about the lateness of the real answer, I should have seen your request earlier since I had a similar problem a while ago.
BuildStarted
A: 

The problem is that ADO.NET team creates the connection as

 connectionBuilder = new SqlConnectionStringBuilder(sqlConnection.ConnectionString)
                {
                    InitialCatalog = "master",
                    AttachDBFilename = string.Empty, 
                };

BUT sqlConnection.ConnectionString is the pure connection string specified in the application config file but without password! due to the security reasons, I think ... so then opening such connection fails!


The only possible solution I found is to use integrated security, which means to set the connection string property Integrated Security=SSPI

And we need to wait while there will be a patch or CTP5 ;o)

frantisek