43

I'm starting to play around with the code-first approach to the entity framework, primarily so that I can decorate my properties with annotations for display in my view (otherwise, right now I have to create a class that is nearly identical to the one that entity framework generated for me just so I can add annotations, and then copy the data from one object to the next).

Right now it looks like when I start my application it is trying to create a database.

I do not want entity framework to ever modify my database. No. Not ever. Don't even try it. It really isn't that hard to modify databases; I would feel much more comfortable if I did that myself. I don't need a framework to hold my hand when designing a database.

Can I tell the framework to stop trying to modify my database? I'm very hesitant to use code-first now as the fact that it's trying to modify my database is rather frightening. Even in development I never want to see it happen.

Am I out of luck?

4
  • 1
    it sounds like your model doesn't exactly match your database. You could try using a copy of your database and point EF at that. Let it create modify the db and compare the differences, then modify your model accordingly. You should also take a look at the EntityTypeConfiguration generic class. Commented Feb 10, 2012 at 15:24
  • Modify schema or modify data? Commented Feb 10, 2012 at 15:34
  • some of us just don't trust these automagical migrations and come from the perspective that designing and setting up the database is important enough that it's perfectly reasonable to do it manually. But get EDMX away from me... Another reason to do this: so one team can work on the DB while the other sets up the classes/models to match - roughly parallel. And if anything changes, you don't have to search back for migrations. Just update your annotations etc. Commented Dec 14, 2015 at 18:30
  • Maybe useful to mention that this behavior was abandoned in Entity Framework core. Commented Oct 31, 2020 at 20:32

5 Answers 5

66

If you don't want EF to create your database, you can disable the database initializer:

public class SchoolDBContext: DbContext 
{
    public SchoolDBContext() : base("SchoolDBConnectionString")
    {            
        //Disable initializer
        Database.SetInitializer<SchoolDBContext>(null);
    }
    public DbSet<Student> Students { get; set; }
    public DbSet<Standard> Standards { get; set; }
}

See http://www.entityframeworktutorial.net/code-first/turn-off-database-initialization-in-code-first.aspx

Sign up to request clarification or add additional context in comments.

7 Comments

You can put it in the static constructor of the context class, as in this example video: msdn.microsoft.com/en-us/data/jj572367
it's not shown in the video. look here instead: entityframeworktutorial.net/code-first/… important is not to use this in front of Database
This answer can be improved with where to add this code.
still can't believe it is the default for it to mess with your database. I don't know why they don't throw exceptions to explain an explicit choice you must make
@Simon_Weaver That's kind of the whole point of code first. You write models to define/create your database.
|
4

If you want to use EF but never modify the database then you probably don't want code first. You probably want something more like database first.

http://blogs.msdn.com/b/adonet/archive/2011/03/15/ef-4-1-model-amp-database-first-walkthrough.aspx

Links from answer comments:
http://automapper.codeplex.com/
Getting Started with AutoMapper

edit: I misunderstood the goal, you should reference this answer where the following correct code was given:

If you don't want EF to create your database, you can disable the database initializer

Database.SetInitializer<MyContext>(null);

5 Comments

I agree that database first sounds like what I want, but I am trying to get around the issue of having to create a class that is nearly identical to the model that is generated for me. I have to create a nearly identical class so that I can decorate properties with annotations for display in my view (e.g. enforcing validation). It results in me having to loop through all of my "EF" objects and copy/map them to my new object that carries the annotations.
I would say that you should never be passing your db model objects to your views. Generally you create another class that is then passed to your view that only contains the properties that are available to that view. You would then decorate that class with your validation properties
@AnthonyShaw - I haven't seen many examples of people doing that, but that's exactly what I'm doing right now. I think I felt apprehensive about it because it seemed like a lot of mundane copying/mapping work. Is there a pattern that you use for turning your database model object into an object for display in your view? How do you usually do it?
@Ek0nomik then perhaps automapper is a solution. It can automagically copy properties from one class to another, given some restrictions (approximately same field names and so on). You still have to define the classes (your own models) however.
@Ek0nomik, like CodeCaster has suggested, I create the ViewModel, if you will, with the properties that I need for the specific view, and use AutoMapper (automapper.codeplex.com or available via NuGet) which uses reflection to map properties (as long as their names match). I originally thought it made for mundane duplication, but as I've continued to do it, I've found many cases where passing my actual object to the view caused issues.
2

When you declare you're initialiser, use the base class:

public class DatabaseInitialiser : CreateDatabaseIfNotExists<MyContext>

rather than :

public class DatabaseInitialiser : RecreateDatabaseIfModelChanges<MyContext>

Or if you use :

Database.SetInitializer<MyContext>(new RecreateDatabaseIfModelChanges<MyContext>);

replace this with :

Database.SetInitializer<MyContext>(new CreateDatabaseIfNotExists<MyContext>);

Comments

1

Since code first pretty much exactly does what you describe, I do not understand your question.

If you don't want EF to fiddle with your database, then generate a model from your existing database.

5 Comments

Right, but if I generate a model from my database, then I am missing the data annotations that I need for displaying data in my views. It results in a lot of duplicate work; essentially creating an identical class as the model that was generated and then decorating those properties with annotations. I am trying to avoid all the copying effort involved with that.
You can decorate generated classes by creating partial classes or buddy classes (MetadataAttribute).
There are examples where you want to do Code Second, the database exists but the relationships dont or your dealing with Views, and a Code Second approach is required.
One reason you might want to switch this off is because you just got an exception telling you that EF tried to DROP your entire database when your application started up!
Perfectly valid for code first to be used to generate database updates but under the control of the user/dbadmin, not "intelligently" wiping all data by itself.
-1

I realize this thread is old but hopefully the OP found the answer. If not...

Have Visual Studio generate the EF6 entity classes from the existing database:

https://www.entityframeworktutorial.net/code-first/code-first-from-existing-database.aspx

and then add (as already said):

Database.SetInitializer<SchoolDBContext>(null);

to stop EF6 from messing with the database.

Note that a potential issue with the auto-generated classes is the resultant code uses fluent.

4 Comments

I'm saying it again to be sure that line of code is added. Someone might use VS to generate the entity classes and then not add the SetInitializer part. That line of code is needed to prevent the database from being created by EF.
So why would that be more sure when there are three answers telling that? Duplicate answers is quite a problem at Stack Overflow. They add no value, only noise.
My answer is not a duplicate. The OP presents two issues: stop EF from modifying the database; and later stated he does not want to create the classes. The former was answered but no one answered the latter. The link I posted answers the latter however the SetInitailizer code is still needed.
No, they want to use their own classes ("so that I can decorate my properties with annotations"), not ones that EF generates. Besides, a link is not an answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.