The following are some very hard learned lessons from using Entity Framework 6 on a non trivial code first project:
- Start by creating database tables first. Yes, these are generated by code first migrations but it is important to think about the domain model as a database represenation. Keep a record of the database so you can compare it to what entity framework creates.
- Write scripts to populate all tables in the database. Place the scripts in separate stored procedures so they can be executed in discrete units.
- Write a script that deletes data from tables one table at a time. Do this in a variety of deletion orders. Checks the cascading deletes are correct. Use the stored procedures to recreate data as soon as you have deleted it. Note that in non trivial solutions, circularity will prevent all cascading deletes being possible.
- Create the class models using the database tables as a guide.
- Use the virtual keyword on properties that you wish to be lazy loaded.
- Create [NonMapped] properties when they can be inferred by querying up the object heirarchy (there is a tendency to create too many properties in code first which would lead to table circularity when the database is generated).
- In the DbContext, set all relationships to non-cascading then specify those you need:
modelBuilder.Entity<Competition>().HasRequired(m => m.Club).WithMany(t => t.Competitions).WillCascadeOnDelete(true);
- Check the generated database tables match the custom ones.
- Create tests that execute the deletion logic you had in scripts. Execute them to check they work.
Good luck, code first is MUCH harder than database first but seems to be what's pushed by the community.