Image datatype in EF 4.1 model first - entity-framework

We have a project which used Entity Framwork 4.0. We draw the model and then generate an SQL Compact 3.5 DB.
Since we needed a large BLOB store, we created a column with the Image data type (since Binary is limited to 8000 bytes). However, when updating to EF 4.1 our model was silently converted to having a Binary column instead!
No worries, we thought, we'll just change it back. Problem is Image cannot be selected anymore! And - specifying binary and setting length to a large value, say 100000, gives an error when trying to generate the DB.
We have found some pointers working with a code first approach, from EF 4.1 Release Notes, A related ADO.net team blog post, A third post describing the related issue and A SO questing discussing the related issue. However, all these talk about the issue using the Code First approach.
Any pointers on solving it Model First?
Thanks!

You need to open model file .edmx with XML editor. And in <edmx:StorageModels> section, change Type for your data Property from varbinary to image.
For example:
<EntityType Name="DataSet">
<Property Name="data" Type="image" Nullable="false" />
</EntityType>
You may also need to manually change the type of the column in .sdf file.
This is a little hack, so you have to do this every time you change your model.

convert your image to a byte array and store it like that then convert to image when you pull it out of the database that is how I store most of my blob type data
as far as the code first approach issues you mentioned is there a specific reason you cannot use code first API and fluent mapping with your database
Edit:
Use the varbinary(max) for datatypes larger than 8kb as image will be deprecated in the future ref
in your edmx file if you are using model first then you can set the column datatype in the properties section when the column is selected in the designer if you are using database first design then you can change the datatype in the database then regenerate model from the database
codefirst api create your data base then use reverse engineer codefirst using entity framework powertools ctp to generate your code first models and context

Related

Entity Framework Database first from non-English DB

I'd like to use DB first Entity Framework, but my source DB is not in English.
Is there a way to intercept the DbContext models generation, and provide a map for some/all table and column names (other language column name -> English column name)?
I'm not sure if there's a possibility to use T4 templates for this.
It seems there was another approach available, and it seemed more suited for me, so I took it.
The main edmx file of EF turns out to be just an XML document, so I created a CSV map file between old/non-English table/column names and created a small nodejs script to replace all occurrences of:
<Property Name="OLD_NAME"
<ScalarProperty Name="OLD_NAME"
<PropertyRef Name="OLD_NAME"
..with new/model names. I applied it on edmx model and mappings sections only, and though not a complete solution it took me 95% there. I still have to rename NavigationProperties, but I'll do it in the edmx designer manually since there aren't many of those.

"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.

Entity Framework model-first design not won't let you edit the table mappings?

If we've been using an Entity Framework 4 model for some time, and we eventually want to switch the underlying database to a different vendor's product (say, from SQL Server to MySQL), is it simple to adjust the table and column mappings in the entity model without needing to update any of the entity class code?
We're trying to design code that is as database agnostic as possible, so I'd like to know in advance how much trouble we're in for if we ever switch our databases around. Ideally, we'd like to not have to touch our applications that use our entity classes. I can't seem to find any way in the entity designer or XML editor to adjust the underlying database column names without it giving me an error.
(I can, however, edit the entity's property names in the designer while leaving the database column names alone, but that's the opposite of what I need.)
Thanks!
EDMX is not database agnostic. SSDL part of EDMX is tightly coupled with database server (in case of MSSQL even with its version). You need separate SSDL for each supported database server.
I don't understand how changing column names relates to database agnostic model. Reverse is true! If you need your database to have different column names for different server products you need separate mapping for each of them!
Changing column names when using model first is possible only if you modify T4 template used for generating database creation SQL script. But every time you create that script designer will delete whole your storage description (SSDL) and mapping (MSL) and replace them with a new one.
The easiest way to have database agnostic code is using code first but even then you can have problems with some type and feature inconsistency among servers.
If you want database agnostic ORM you should probably check NHibernate.

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.

Entity Framework: Ignore Columns

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.