Pretty new to all of this MVC/EF stuff and was wondering how to properly handle code first class changes.
I had a class that was point to a production database to retrieve and store information. When defining the database context I had it pointing to a table, however I wanted it to look at a view so changed it. It then started going a bit loopy and said about code migration. The view existed and all was correct.
To correct this I used the SetInitializer for the context to be false in the Global.asax and all worked fine.
Sorry I don't have my code to hand to paste and don't know it well enough to write off the top of my head.
Anyhow, my question is I thought the hole point of the class and context as to define it, if I changed that in code then wouldn't that be enough? Migration seemed to want to change or update the production database!
Is there some meta data behind the model class and context that snaps shots the data base in code first that is accessible that should be changed or is the SetInitializer the correct path to use in this scenario?
TO be sure I am using Code first I basically manually code the model and then define it using DbSet<> in the database context
Related
This is probably the single biggest time-waster I have: I must have wasted cumulative days trying to get round it.
I'm using Visual Studio 2015 and ASP.NET MVC 5, but don't think this is important - I've had this problem in other versions. I accept that it's based on my ignorance.
I've got a reasonably complicated SQL Server database, and am using database-first model generation. To keep things manageable, I've got about 20 different models, each containing tables on a particular theme.
So let's say I want to generate a model to contain tables to do with the maps in my database. First thing to do is to add a new entity model database:
I want to call my model webMap:
I choose to generate the model from my database:
I've got a perfectly good connection string to the database in my web.config file, so I use that and choose not to save this:
I then choose the tables for which I want to generate classes, and these options:
What happens then is that it doesn't recognise the new database context:
The reason is (I think) in this file:
This has created a class named after a connection string:
If I change the partial class and constructor name like this:
then it solves the problem - until I next need to update the database.
Please forgive my ignorance about what's going on. Although I like what entity frameworks do, I find the opacity of what's going on hard to work with. Could any kind person tell me what I'm doing wrong, without delving into T4 transformations? I've tried cleaning my solution and running custom tools, by the way. Thank you!
Open the edmx file in the designer and click somewhere inside to select the conceptual model in the Properties window. Now look at Entity Container Name property. The value should be Entities - I think derived from your connection string name and no way to be specified during the Add wizard steps.
Simply change it to the desired name of the context (like webMap), save/build and you are done.
But make sure the Namespace and Entity Container Name property values are different.
Many thanks to Ivan and garret for their answers. I've collated the information and put here a procedure which worked for me. I don't claim to understand fully what's going on (but surely the point of a framework like this is that I shouldn't need to?).
Here's how I managed to create my model. There are 6 steps. I don't know which of them can be omitted, but following them all solved my problem.
Step 1 - Delete any existing models referencing tblMap
I found that I had inadvertently created another model. Doing a global search for (in my case) webMap can help find if you are in the same position.
Step 2 - clear the web.config file connection strings
I don't understand why, but it appears that the connection strings in your web.config file show up as conflicting names in code. So I did a search for webMap in my web.config file and deleted all connection strings containing it. I think this is the step that I had previously omitted.
Step 3 - Clean and rebuild the solution
I cleaned the solution (no idea if this was necessary), then rebuilt it to ensure that the only errors I had left were in my code referencing the webMap database context which no longer existed.
Step 4 - Follow the steps to add an ADO entity model
But ... call the item name in the first screen something like webMapModel, the connection string something like webMapEntities (and choose to save this in the web.config file) and the namespace something like webMapNamespace. Note that none of these is the webMap name I want to end up with.
Step 5 - Change the entity container name
Double-click on the model .edmx file which has been created to open it (this might not be necessary - it may be open already). Click on the white background of the model to deselect any entities. Press F4 to bring up properties.
Change the entity container name to webMap as shown above.
Step 6 - Rebuild your solution
At this point all my errors disappeared!
Name of Your context, should be different than namespace.
Try to use this configuration:
And in next screen:
And yes, it will add next connection string to web.config, but it's ok.
I have what feels should be a simple problem, but cannot find a simple answer.
I have a simple migration, I just need to add a synthentic property for use in a Fetched Results Controller. This new property is just a BOOL (used for sorting) that is derived from another property.
Example:
var title: String? // "engineer" | "accountant"
var hasTitle: Bool // title != nil
Simply, I need to add the new field hasTitle (which seems trivial), and the populate it once. I want to keep this code out of my normal app logic, so I don't have to code in a history of all my schema changes.
Is it possible to do a lightweight migration followed by an isolated, one-time mass update, or do I have to do a custom / heavyweight migration.
And secondly, if I need to do a custom migration, are there any mitigating techniques - can I use a Value Expression "Function" to do initialize the above (title != nil)
What I want to avoid is having to set a NSUserDefaults flag for a migration, and check that on every launch. I would like to contain the complexity of the migration to migration specific code and not pollute the regular app logic.
Thanks!
Is it possible to do a lightweight migration followed by an isolated, one-time mass update, or do I have to do a custom / heavyweight migration.
Both are possible. I'd go with a custom migration, simply because it'll save you from having code that needs to check on the new attribute every time the app launches. For a simple change like yours it's pretty straightforward, although it's uncharted territory for most iOS developers. I recently described the process in detail in another answer.
If you don't go with a custom migration, you'd need to make the new attribute optional and then add some custom code to check if a value exists and assign one if it doesn't. It might seem simpler, but that's just because it probably seems more familiar. Core Data will save you from needing to insert this kind of check in your app launch process, and ensure that your conversion code runs only when a conversion is actually needed.
I have to write an application which is creates/updates/deletes database entries. This part I've done, however I must also implement a function that returns the current size of the database in KB/MB which I'm having bigger problems with.
Basically I'm doing Code First, so I created the model class and the DBContext class for it which returns value I need.
Is there a way for, let's say a DBSet, to somehow get the size of my DB entries in KB/MB? I've googled to find if maybe there are some other helpful classes for this but no luck.
Being fairly new to CoreData (Started playing with it 2 hours ago ;) ) I keep wondering if there is an easier way to do things.
I'm currently using a DataModel to create my persistant objects code.
However when I keep adjusting things like number of attributes sotred, the name of the fields etc... and that leads to having the update the code of my NSManagedObjects.
I found that you can create the classes with the attributes already implemented, however, I haven't figured out how to update the code of an existing class other than adding it by hand or creating a new object and overwriting the existing one? (or how do other developers do it)
I'm aware that the answer is surely: "there is no better way" but I still have to ask.
Check out mogenerator.
This command line utility will generate two class files. A machine generated _MyClass header and implementation, with all code for your model. It will also create a subclass MyClass where you can add your own customizations.
Each time you regenerate your code, only the machine generated _MyClass files will be updated. All your changes to MyClass will be preserved.
If you can not use mogenerator, you can use the native code generation. Make sure you regenerate the code every time. However, that will erase any changes.
So, you have two very viable options.
Write a category on the entity class. You can do just about everything you want with a category.
Subclass from the entity, and put all your code in there.
Personally, I prefer using categories unless I absolutely must inherit... which is extremely rare.
Is there a way when i add a new entity to my Code First configuration the table gets automatically added so i don't have to worry about updating my DB with new tables?
you can add
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<YourDbContext>());
in you r application start . It will recreate database for you if you have modified your configuration.
And if you do not want to drop and create database (To incremental development) you can use SqlMigrations. http://www.hanselman.com/blog/EntityFrameworkCodeFirstMigrationsAlphaNuGetPackageOfTheWeek10.aspx
From: http://blogs.msdn.com/b/adonet/archive/2010/12/06/ef-feature-ctp5-code-first-walkthrough.aspx
Setting an Initialization Strategy
In the next section we are going to start changing our model which in turn means the database schema needs to change as well. Currently there is no ‘out of the box’ solution to evolve your existing schema in place. Database evolution is something we are currently working on and a sample of the direction we are heading is provided in a recent design blog post.
There is however the opportunity to run some custom logic to initialize the database the first time a context is used in an AppDomain. This is handy if you want to insert seed data for test runs but it’s also useful to re-create the database if the model has changed. In CTP5 we include a couple of strategies you can plug in but you can also write custom ones.
Add a using statement for System.Data.Entity.Database at the top of Program.cs
using System.Data.Entity.Database;
For the walkthrough we just want to drop and re-create the database whenever the model has changed, so at the top of the Main method in my Program class I’ve added the following code
DbDatabase.SetInitializer<ProductContext>(
new DropCreateDatabaseIfModelChanges<ProductContext>());