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.
Related
I'm using 'EF Designer from database' approach. In my generated models I have a few ICollections that I don't really need. Can I remove those ICollections without breaking stuff?
Depending on what they are actually being used for you may be able to remove them without breaking anything, if you know what you are doing.
The problem is, as it is with any auto generated code, that if you make schema changes down the road and need to regenerate your model whatever you have removed will be added back.
Therefore, the recommended approach is to remove the collections that you don't need from your model in the model designer and generate the model without those collections.
Backgroud:
EDMX was built pretty straight forward, I just selected all tables and clicked "Ok" button several times, the thing is, not all the columns are/will be consumed by system.
What happened
Later on, several nice-to-have columns became "kiss-good-bye" columns, and bam, several components stopped functioning as exceptions are thrown from entity framework saying "Invalid Column Name xxxxx"
What is wanted to be achieved
Hopefully the legendary gurus in stackoverflow will kindly shine light on "how to let EF ignore unused columns, even if they are no more in DB".
System design sometimes would like some room. so there go all the candidate columns that might not be in use after a while, yet DB-First approach takes in all the candidates, it's possible for MS to come up with some kind of a policy to ignore unused properties, and the complexity and cost to implement this mechanism seems not very high.
In Following there lays a few things I tried but didn't have any luck, maybe it's the way I tried it, or it's just not the thing to turn things around.
Method #1 tried on my side
Implementing data loading in a more column-specific way, Table1.Select(Column1, 2, 3, 4);
Why I dropped it: it's just too much for me to rewrite so I didn't even verify whether it solves the problem.
Method #2 tried on my side
Why I dropped it: it just doesn't work
Method #3
DefaultValue=""
Why I dropped it: it just doesn't work, still got "invalid column name" exception
#4
Database.SetInitialize
Why I dropped it: it doesn't work
If your database schema changes, you need to update the EDMX model in the Designer. Right click in the white space and click "Update Model from Database...". This needs to be done every time your schema changes.
After a while of research, now I have some workaround, but I haven't got any solution to this.
Inject Data Contract into EDMX calls so that EF will only retrieve the columns required by upper layers.
Pros: this is hopefully one-shot-two-birds straight forward, using the mapper between Data Contract and EDMX Schema to make EF calls.
Cons: Perf is a concern, hopefully latest version reflection won't be taking up too much CPU Span, and also implementation will have to be a lot to cover all EF calls.
Set up a Unit Test case,
Steps Retrieve currently-used EDMX from DLL Resource Section, Retrieve latest EDMX from DB, if actual doesn't match expected, alert EDMX owner in the Dev Team.
Expected Result on-the-fly exported EDMX
Actual Result existing EDMX exported from DLL Resource Section
Wish this helps.
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.
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.
I have a database that I wish to build an EF model from, however I do not want to include certain columns from the database as the columns concerned are maintained exclusively on the server and should not be manipulated by any application.
Both of the columns are DateTime (if this makes any difference), one of the columns is nullable and is maintained by a trigger on updates and the other is not nullable and set using a default value in the table definition.
I guess I am looking for something like the "Server Generated" option in Linq2Sql; but I cannot find such an option.
Can anybody tell me how to work around this?
Caveat:
I have been trying to introduce business object modelling at my place of work for some years and it has always been rejected because of the amount of additional code that has to be hand-cranked. EF is currently being seen as a viable solution because of the designer and code generation therefore any option that involves hand-cranking the XML will only turn the rest of my colleagues away from EF. I am therefore looking for something that can be done either using the designer or using code.
EDIT:
I guess that what I am looking for here is either...
(a) a way to create the model without EF referencing the columns in the store (ssdl) and therefore not looking to manipulate it in any way
(b) a way to programatically set the "StoreGeneratedPattern" attribute against the property when I create the ObjectContext (the easy answer is to manually manipulate this in the .ssdl, but this would then be overwritten if I refreshed the model from the database and I cannot go down the route where the .csdl, .msl & .ssdl are hand-cranked).
Can you do this with the Entity Framework? Yes; it's easy. Can you do this with the Entity Framework designer? Unfortunately, that is much harder.
The problem you're having is that the column exists in the storage schema (SSDL) in your EDMX. Removing the column with the GUI designer simply removes it from the client schema, not the mapping or the storage schema. However, it's simple enough to go into the EDMX and remove it. Having done that, you can also remove it from the mapping in the client schema portions of the EDMX, and the entity framework will longer complain that it is unmapped.
Problem solved, right?
Well, no. When you use the GUI designer to update the EDMX from the database, the storage schema is thrown away and re-generated. So your column will come back. As far as I know, there is no way to tell the GUI designer to never map a particular column. So you will have to re-do this every time you update with the GUI designer. Fortunately, the EDMX is XML, so you can do this with a XML transform, LINQ, or the XML tool of your choice.
Can you not create a view with the columns you need and import it through entity function wizard and map it to your entities?
You could modify the text template to ignore these columns when generating your entity classes. For example if you added "IGNORE" to the documentation summary, you could modify the template to ignore them by replacing;
Dim simpleProperties as IEnumerable(Of EdmProperty) = typeMapper.GetSimpleProperties(entity)
with;
Dim simpleProperties as IEnumerable(Of EdmProperty) = typeMapper.GetSimpleProperties(entity).Where(Function(p) p.Documentation is nothing orelse p.Documentation.Summary.IndexOf("IGNORE")<0)
Right click on the field in the graphical representation and choose delete. Ive found that sometimes you will get errors when you make a lot of changes to the modeling at once and start to lose track of your changes. Your best bet might be to rebuild the EF generated model.
Keep in mind that when you "update from the database", that old fields on the generated models will not be removed, you will have to remove them manually. For example if you renamed DateField1 to DateField2 in your database, and then you "Update Model from Database", you will now see both DateField1 and DateField2 on the resultant model. This can be a cause of errors.
Do you not want the column to appear in the model at all?
Try selecting the column in the Designer view and hitting the delete key.
Edit
You could make the setter for the property private. Then your app won't be able to modify the value.
Timestamp is a different data type than DateTime. Timestamp seems to be recognized as an attribute the engine manages, much like an identity attribute. You can't "update" a timestamp attribute. Hence, the EDM can manage it correctly (just as it does an identity).
In EDMX designer, select the property and set StoreGeneratedPattern to Computed.