How do you update an edmx file with database changes? - entity-framework

I have an edmx file and I changed a table in my database. I know that there is an "Update Model from database" wizard, however in many cases this is useless.
For example if I change a field from non null to nullable or if I remove fields the update model does not reflect the changes. I have had to remove the entity and add it back in to get the changes to appear in my model.
Per the following question:
How do I propagate database changes to my .edmx file?
One of the answers seems to say the same thing, that you need to remove the entity and add it back in.
Is this the definitive answer or is there a better way to do this?

Updating an EDMX the safe way:
As you have found, the update from database does not always change existing properties correctly.
From our day-to-day use of EDMX updating (100s of updates over 24 months), I would recommend the following sequence for updating an EDMX.
Delete existing model and then update:
Open the EDMX designer
Ctrl-A to select all
Delete key to delete all models in the designer
IMPORTANT: Do not save the EDMX at this point if you are using TFS for source control!*
Now right-click and select "Update Model from Database" to recreate the entire model again.
Rebuild project to propagate changes
This will obviously lose any manual tweaks you have made to the model, but manual tweaks are to be avoided if possible. This makes the entire process reproducible at any time (which is a good thing).
Important notes:
If you have auto-save turned on in Visual Studio, you need to select the update (step 5 above), quickly to avoid an auto-save saving everything.
If you are using TFS for source control, and happen to save the EDMX after emptying it, TFS will mark all the generated files as "deleted" and updating the EDMX again can result in disconnected files that are not in source control!.
This process will not update any stored procedures. Further, I have found that a refresh of an EDMX will also not update stored procedures where just the return type has changed (still current as of EF 6.1.1).
Additional Recommendation:
Keep your EDMX in a separate library. This also becomes a great place to add additional TT files and partial classes (e.g. to extend function of EDMX models). I also place any extension methods for the database context in this library. The migration files get generated in the library too keeping it all nicely contained.
Update April 2015
The latest Release 4 of Visual Studio 2013 appears to have resolved a lot of the TFS issues. We now see Visual Studio checkout generated files, then revert them if they are unchanged. The above steps still appear to be the safest approach.
Update September 2015
Using latest VS2013 Release 5, we still have issues if a save occurs during EDMX update. You can still wind up in a state where pending deletes causes your tt files to be removed from source control during the update. The secret is to update fast between steps 4 and 5! :)

An important first step is to understand exactly what happens when you use the update model wizard.
From the MSDN Library:
The ADO.NET Entity Data Model Designer (Entity Designer) uses the Update Model Wizard to update an .edmx file from changes made to the database. The Update Model Wizard overwrites the storage model as part of this process. The Update Model Wizard also makes some changes to the conceptual model and mappings, but it only makes these changes when objects are added to the database. For example, new entity types are added to the conceptual model when tables are added to the database, and new properties are added to entity types when columns are added to a table. For details about what changes are made to the .edmx file, see Changes Made to an .edmx File by the Update Model Wizard.
When you updated the database using the update model wizard, it updated the storage model in the .edmx file and not the conceptual model. When changes are made to the definition of existing objects, only the storage model is updated; the conceptual model is not updated. For a complete description of changes that are made by the update model wizard, please see the "Changes Made to an .edmx File by the Update Model Wizard" link above.
Here are some options on how to update objects that are not updated by the update model wizard (based on your scenario where a the column definition was altered):
Use the update model wizard (to update the storage model), open the .edmx file using the designer (default), find the desired scalar property and edit the desired properties in the Properties windows.
Use the update model wizard (to update the storage model), open the .edmx file using the XML editor, find the desired property in the CSDL (conceptual model) section and change the desired attributes. This is basically the same as option 1, but you're editing the XML directly (a find and replace might be useful here).
From the Model Browser, delete the desired entity from the Entity Types section of the conceptual model and the desired table from the Tables / Views section of the storage model. Then use the update model wizard to add it back.
The best option would depend on the given scenario. For example, if you just altered the definition of one column, then option 1 is likely you best choice. If you altered the definition of a number of columns in a single table, then option 3 might be your best choice. If you altered a column that is used across a number of tables (such as a primary / foreign key), then editing the .edmx XML directly might be your best option.

Consider I have added a new column(c1) to my existing table. Then to update the same in my existing Entity Model, I would do the following.
I will open the .edmx file in notepad ++.
I will add the property c1 to .edmx file where ever necessary. For example I would add c1 node below every c0 node.
<EntityType Name="table">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="int" StoreGeneratedPattern="Identity" Nullable="false" />
<Property Name="c0" Type="nvarchar(max)" />
<Property Name="c1" Type="nvarchar(max)" />
</EntityType>
Reload the project in Visual studio.
And finally add the attribute c1 to the model.

Step 1:
Double click on .edmx file. (Diagram Window will open)
Step 2:
On the diagram window, right click and select Update model from database... (Now it will update only in update storage but not in model)
Step 3:
Right click on Model.tt file and click on Run Custom Tool (Now it will be updated in model too)
That's It!

If I understand your question and your example, once you do the update model from database step and you're sitting there on the Model.edmx diagram, you can highlight the property in the class that you want to change and show the properties on it, and change the Nullable property for it to Nullable: True. That's at least one way to do this.
I believe the idea here is that conceptual model (that isn't being changed from non-null to nullable) can actually differ from the underlying database table and so it doesn't change that part and that difference might be exactly what you intend. The two ways I handle this are either doing the remove & add as you mentioned or more typically I manually set the properties as I mentioned.

Firstly, double click .edmx file
Secondly, Right Click on the Empty space and select "Update Model From Database"
Thirdly, Select Refresh tab on the menu bar.
Lastly, Select the table you want to refresh and select Finish..

Related

Stop Entity Framework from updating edmx model with a column that isn't needed

I have rowguids in all my tables to help with change tracking in all my tables. I don't want/need these tables in my edmx or my entities. However, I do still need to make changes to other things sometimes so everytime i go to update model from database in the edmx it adds all the rowguids in all my tables everytime and i have to manually delete each one. Is there a way to handle this from happening? Is there a way I can maybe edit the T4 to maybe ignore that 'rowguid' column?
Database first Entity framework
I don't believe there is a way to intrinsically tell the edmx to not pull certain columns. Because you want to prevent it in both the entities AND the edmx, altering the T4 template will not help you prevent it from being added to the edmx.
If you change your mind you could certainly prevent entities with a certain naming convention from being added in the T4. I prefer to keep my edmx files clean, and manually deleting is the only way I know to remove unwanted columns.
For others who may be interested in understanding EF T4 here's a basic article that I've found helpful in better understanding what it does and how it works:
http://msdn.microsoft.com/en-us/data/gg558520.aspx
To your question about generating a scrub script: edmx files behind the scenes are just xml markup trees. Every element shown in the viewer corresponds to one or more element in the tree. Here is a simple example of what the xml might look like for a simple Program entity.
If you wanted to scrub specific columns you could remove them from the underlying xml.
<EntityType Name="Program">
<Key>
<PropertyRef Name="ID" />
</Key>
<Property Name="ProgramName" Type="varchar" MaxLength="150" />
<Property Name="DateTimeCreated" Type="datetime" />
</EntityType>
Sadly, this is not all you would also need to edit there are two locations in the edmx this and the conceptual model. you might also have to remove associations if they reference the deleted property.
You will also need to edit the msl. I was hoping to mock up a personal example, but in lieu of that I have found two articles that discuss or examine the process others have gone through for this.
http://social.msdn.microsoft.com/Forums/en-US/e61192da-8c51-4f17-8745-c4455c836f9d/ef-modify-csdl-ssdl-and-mapping-in-code-and-then-save-in-the-csdl-ssdl-files?forum=adodotnetentityframework
http://blogs.msdn.com/b/dsimmons/archive/2007/12/07/how-to-use-your-existing-csdl-msl-ssdl-files-in-the-entity-designer-ctp2.aspx
These two might give you a better idea of what's involved in that process. It might still be worth it for you if it's a severe use case.
If there are tables you do not want in your .edmx or entities, then don't select them when you create the entity data models.
When creating the entity data model in the wizard, go for "EF Designer from Database" (database first).
To get there, right click the solution -> Add -> New Item... -> Under the 'Data' category, select a new ADO.NET Entity Data Model -> 'EF Designer from Database'
After the connection settings prompt, make sure you only include the tables you want.

Entity framework: Manually maintained mappings

I've been using EF for a while (4 with model first) and so far I've not created any mapping manually. Whenever I need more entities/tables, I add an entity and the associations (all foreign key) and click "update database from model", which, as is well known, doesn't update any database from the model (although it does need a database connection for reasons I don't know). What it does is generating a storage model and the appropriate mappings to it, which are all stored back to the same edmx xml file.
So far, that has always been enough for me but I'm wondering what the workflow would be if one is to tweak the mappings and storage model manually. "Update database from model" overwrites all manual customization - so how is one to fix most of the mappings and storage model? Because I clearly don't want to do it all by hand - in fact I couldn't even figure out how to actually create a table in the storage model other than by editing the edmx in the xml.
I have the same problem. I just use a mixture of methods. If I add a field to the database, I just add the field to the model file. If I do a major restructure, I delete the table and recreate it by generating it from the database. Sometimes, I actually edit the edmx as XML to change or add things. You just kinda gotta figure out what process works best for you. I have managed to avoid heavy customization in the edmx by using the T4 template or changing the database and regenerating.

Selecting specific entities to model in EF

So When I use the EF wizard right now and choose a view, it creates entities for every column in the view. How can I select entity generation for a specific few columns? I don't need all of them. Also, the DB schema changes often. Anything I can do to make sure it doesn't break my app?
You asked two questions, so this will be a two-part answer.
[Answer 1] There is no way to choose specific columns when generating the model via the wizard. However, once the model is generated, deleting a property will remove it (and its mapping) from the model. (Note that non-nullable columns will need to be surfaced as properties or you will get errors).
[Answer 2] In terms of responding to a schema which changes often, your best bet will to make sure you understand what is going on underneath your model. The EDMX contains 3 sections:
The "CSDL" - this is the "conceptual model" where your entity definitions are stored.
The "SSDL" - this is the "storage model" which keeps track of the state of your database.
The "MSDL" - this defines the mapping between the two.
When your DB schema changes and you run the "update model from database" wizard, your CSDL and SSDL may get out of sync. This is because the SSDL gets updated with the changes, but the CSDL will not (unless you are adding something new). Now, for the most part, this is a good thing, because it will not blow away any changes you've made, so your model will still work with your application logic. But you may see errors due to the changes in the SSDL.
There are a few ways to fix this:
If the changes to the database were relatively simple (added columns, renamed tables, etc) you might be able to simply redefine your mappings (using the "mapping details" window available in an entity's context menu). This does require some manual work. For instance, if new columns are showing up in the SSDL you'll need to add the corresponding properties yourself. You may even need to re-map an entire entity if your tables get renamed or too many mappings get dropped.
You can remove affected entities from the model and re-add them using the "update" wizard. This will blow-away any customizations you had made, and might cause some of your application logic to break. But if you are happier responding to database changes by updating your application's code than by mucking around with your entity mappings, this could be another option.
You can edit the XML manually. The designer isn't perfect for every situation, so if worse comes to worst you can always use the XML editor.
Hope that helps! There may not be a perfect solution, but it should get you most of the way there.

"Update Model from Database" does not see a type change

I have several columns that I changed from Int to BigInt.
I opened up my EF model and did an 'Update Model from Database' and expected to see those columns now be Int64s. But they are still Int32s.
(I ran it several times just to be sure.)
I double checked my database and the columns are definitely BigInts.
So... does 'Update Model from Database' not work for a change of data type? Does it need to be manually applied?
Unfortunately, you'll need to delete the items from your model and then add them back in - at least that's the only thing I have managed to get working.
There is at least one third-party tool that is supposed to help with this, but have not tried it personally.
I'm using VS2008 SP1. If you change the datatype in the "ModelView" (CSDL) of the edmx, errors will occur because the "DatabaseModel" (SSDL) is not updated. You have to edit the *.edmx manually (XML). That is not so hard as it sounds.
You can simply search for the Property that the "Error List" of VS provides you (search in files is maybe the best solution for this). Go to the line where the wrong datatype appear and fix it.
e.g. you changed float to nvarchar(50) on the database --> go to your model and change Double to String --> validate --> Error.... --> Search for the property and make following changes:
<Property Name="YourChangedProperty" Type="float" />
to
<Property Name="YourChangedProperty" Type="nvarchar" MaxLength="50" />
This works very well if you know exactly what you've changed on the database. If you've made countless changes, you would have to analyse your changes with some DB-compare tool or regenerate the whole model.
Not very nice. But it "works".
take care
M
Correct - data types don't appear to update automatically. You can simply change the data type in the model view using the Properties window and change the Type to Int64.
Answer
For the specific scenario you mentioned, you will need to manually change the Type from Int32 to Int64.
There are a number of ways that this can be done, but the easiest is probably just to open the model (using the default editor) and change the Type of the property from Int32 to Int64.
Explanation (from MSDN Library)
The ADO.NET Entity Data Model Designer (Entity Designer) uses the Update Model Wizard to update an .edmx file from changes made to the database. The Update Model Wizard overwrites the storage model as part of this process. The Update Model Wizard also makes some changes to the conceptual model and mappings, but it only makes these changes when objects are added to the database. For example, new entity types are added to the conceptual model when tables are added to the database, and new properties are added to entity types when columns are added to a table. For details about what changes are made to the .edmx file, see Changes Made to an .edmx File by the Update Model Wizard.
For your scenario, the important thing to note is that the update model wizard is updating the .edmx file with your changes, but only to the storage model. When changes are made to the definition of existing columns, the conceptual model is not updated. For a complete description of changes made by the update model wizard, please see the "Changes Made to an .edmx File by the Update Model Wizard" link above.
You need delete your EF model and than create again and will work.
This may be an older question, but it is most assuredly still relevant today as the issue has not changed. As such, I thought I'd offer a synopsis of the research performed to date on the issue, including some observations of my own:
This failure to update the existing data-types is by design, based upon notes attached to Microsoft's documentation on the topic, as reported in the answer from timb. (Note that Microsoft appears to have either moved or purged the linked document and current documentation does not refer to this issue, but similarly worded notes can still be found elsewhere in archived documentation. Reference) The "Update Model from Database..." wizard does not update those changes, and instead pushes the onus for resolving the issue back onto the developer, in order to avoid making incorrect automatic changes which could theoretically corrupt the Model in ways which were not intended by the developer.
As such, there are really only two ways to resolve the issue, without resorting to third party tools:
Delete the affected tables from the Model and re-add them with the "Update Model from Database..." wizard, as noted in the answer from E.J. Brennan. The potential weakness of this method is that it doesn't always succeed, particularly if the original model was generated using a previous version of the Entity Framework, which can sometimes force the developer to perform significantly more work than might otherwise be necessary to complete the task.
Manually adjust the affected fields from the graphical model viewer, by right-clicking on the field in the table and selecting "Properties..." from the contextual menu. NOTE: Do not make manual changes directly to the Model .cs files from a code window, as such changes will be reverted the next time the "Update Model from Database..." wizard is run; if the changes are performed from the graphical model viewer, they will persist beyond re-running the wizard.
Also if you work with MySQL on Windows - recreating model may also wont help. Schema is somehow cached in MySQL. So if model is not updated even after recreation try to restart MySQL service and VS to be sure. After that model should be successfully updated.
I solved this by modifying the .EDMX file with a text editor.
Find your value and change it's type. Then correct the type in other errors that will be shown in the debugger.

How can I make the Entity data model designer use my database column descriptions?

I am using EF4 with Visual Studio 2010. I have a SQL database already created and all my columns are documented with the Description property in SQL management studio. When I create the edmx in Visual Studio, how can I make it read those descriptions and use them to add comments to my generated classes? I know I can use the Summary and LongDescription in the edmx properties but I'm looking for a way to do this without having to copy and paste every description.
Thanks!
There is a feature request for this. Feel free to add your votes to help make this available in the future:
Retrieve the SQL Descriptions in Entity-Framework feature request
Huagati has some great tools for working with EF and L2S. One of the features is updating the EF documentation based on the SQL database:
Huagati website
From the website: Update ADO.NET Entity Data Model documentation from database retrieves free-text table and column descriptions, and index definitions from the database and updates the xml documentation fields in the EDMX designer with the descriptions.
It seems they look for these fields in the database and then update the model XML directly. Probably someone could create a VS Add-In that would do the same without the price if this is the only feature you wanted. I'll add this to my list of "future" projects (though I never seem to find time for these!).
Hope that helps!
I've been looking at ways of hacking something together to populate the edmx with the meta data from the database.
The summary and long description edmx properties are stored in elements under the EntityType element.
<EntityType Name="EntityName">
<!-- Without this element classes are typically generated with
"No Metadata Documentation available." -->
<Documentation>
<Summary>Entity Summary</Summary>
<LongDescription>Entity Long Description</LongDescription>
</Documentation>
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="String" Nullable="false" MaxLength="25" Unicode="false" FixedLength="true" />
<!-- Lots of other properties -->
</EntityType>
The relevant section of the edmx file, the Store Schema Definition Language (SSDL), is created by System.Data.Entity.Design.EntityStoreSchemaGenerator.GenerateStoreMetadata(). Or at least this is the case with EdmGen.
I'm going to see if the EntityStoreSchemaGenerator.StoreItemCollection can be modified before being used by EntityStoreSchemaGenerator.WriteStoreSchema(...) to output the XML.
Update
Well that was annoying. System.Data.Metadata.Edm.Documentation is sealed and only has an internal constructor. Both properties of interest can only be set internally as well.
So it seems like a dead end approach.
I don't know that the designer itself has any extensibility points. However, once the Summary and LongDescription fields are populated in your edmx file, those value will remain there, even if you make other changes or re-updated your model from the database. Unless you delete a table and re-add it, those values will remain populated.
So you could either just copy and paste them all in one at a time (how many tables are in your model? This goes quicker than you think), or write a program to extract the info from your database (using SQL SMO or something), and have that program edit your edmx file, populating the Summary and LongDescription fields (make a backup of your edmx each time you try your program -- you don't want to botch your edmx file and have to start over).
If you have large models, and you're making lots of them, writing a program to do it automatically is worth your time. If you've only got a few models, with not too many tables, copy paste it is.
You might want to think about submitting feedback to the Entity Framework team here. Seems like the designer should automatically pick up on the description field from SQL Server. Would make a good feature request.