How to preserve non-nullable setting in edmx when refreshing model? - entity-framework

I have a project that I recently migrated from VS2010 to VS2012.
It contains an EF4.1 edmx file containing my entities. A few of these entities are based on views and are read-only. Although some columns returned by the views are nullable, I have changed the return value of these columns in the view to ensure that they do not return null by using
ISNULL(NumericColumnName, 0) AS NumericValueColumn
When updating the model via the "Update Model From Database" function in VS2010, the columns that were returned in this way were being created as non-nullable in my model. However, since the move to VS2012, this is no longer the case.
Now, whenever I use the "Update Model From Database" functionality, these properties are generated as nullable. What I have to do is manually set the columns to non-nullable. However, the entity properties will be regenerated as nullable the next time that I run "Update Model From Database". I then have to update them to non-nullable again.
Another work-around that I have tried is to move the view-based entities to their own edmx file. However, I am seeing the same behavior when updating either of the edmx files.
Another detail is that I am using Self-Tracking Entities, generated via the EF4.1 T4 STE templates.
Is there any way to prevent the VS2012's EF designer from overwriting my non-nullable attribute for the view-based entities?
EDIT
It turns out that the designer in VS2012 is trying to prevent you from shooting yourself in the foot, and consequently changes the member properties inside my entity.
When generating a member from the following:
SELECT ISNULL(Quantity,0) * ISNULL(Number, 0) AS Total FROM SomeTable
VS2012 will always set the member Total on the SomeTable entity to nullable because it does not understand that there is no way for the result of the multiplication to be 0. To prevent this behavior, change it to:
SELECT ISNULL(Quantity * Number, 0) AS Total FROM SomeTable.
Watch out for aggregations as ISNULL(SUM(SomeCol),0) is not the same as SUM(ISNULL(SomeCol,0)).

Related

Entity Framework 4.1 Complex Type reuse in different models

Here is the senario for which I could not find anything useful. Maybe Im the first person thinking of doing it this way:
Approach: Database First
Database: SQL Server 2008 R2
Project : DLL (Data Access)
I have a data access library which encapsulates all the access to database as well as the biz functionality. The database has many tables and all the tables have the following 2 columns:
last_updated_on: smalldatetime
last_updated_by: nvarchar(50)
The project contains several models (or edmx files) which contain only related entities which are mapped to the tables they represent. Since each of the table contain the columns for last_updated_* I created a complex type in one of the models that is as follows:
Complex Type: History
By (string: last_updated_by)
On (DateTime: last_updated_on)
The problem is that it can only be used in the model in which I defined it.
A) If I try to use it in other model it does not show it in the designer
B) If i define it in the other models I get error History already defined
Is there any solution so that the History complex type, defined in one model can be reused by other models?
I was trying to do almost the exact same thing (my DB fields are "created", "creatorId", "modified", and "modifierId", wrapped up into a complex type RecordHistory) and ran into this question before finding an answer...
http://msdn.microsoft.com/en-us/data/jj680147#Mapping outlines the solution, but since it's fairly simple I'll cover the basics here too:
First create the complex type as you did (select the fields in the .edmx Designer, right click, select "Refactor into New Complex Type")
In the .edmx Designer (NOT the Model Browser) right click on another table/entity that has the same common columns and select Add -> Complex Property
The new property will be assigned a complex type automatically. If you have more than 1 complex type, edit the new property's properties and set the Type appropriately
Right-click on the table/entity again (in either the Model Browser or Designer) and select Table Mapping
Update the Value/Property column for each of your common fields (changing them, in my case, from "modified : DateTime" to "history.modified : DateTime")
Delete the old common fields from your entity, leaving just the complex type in their place

EntityFramework inheritance - Ignore not nullable column

I have an one entity in my edmx model having an one property that can contains huge XML data.
Basically I want to load this entity without this property (column) /* huge data loading */ . And load this column only when it is strictly needed.
I have tried to create an inherited entity containing this property and remove this property from base entity (original entity). I have done mapping.
At this time I have problem, that during compilation a I get error, that base entity is not capable to insert and update itself, because property is not nullable
I am looking for best approach (solution) how this situation should be solved.
I am attaching the cut-out from my emdx designer (containing my current and desired situation)
UPDATE:
I will try to write a procedure that I have tried:
I mapped functions to my custom functions. For entity TRP_TechReport_T without the XML column (property). Then I just mapped for entity TRP_TechReport_T functions to my custom function (containing XML column).
Then I set Mapping condition on the entity TRP_TechReport_T: When TRP_XML = Empty.String
TechReport_T mappings:
TechReport_T functions:
TechReportFull_T mappings:
TechReportFull_T functions:
At this moment I get error:
Error 2 Error 3032: Problem in mapping fragments starting at line 3754:Condition member 'TRP_TechReport_T.TRP_XML' with a condition other than 'IsNull=False' is mapped. Either remove the condition on TRP_TechReport_T.TRP_XML or remove it from the mapping.
The column is not nullable in the database and mustn't be.
I can hard-set XML property to nullable, but in the case of the model updating from the database information will be lost.
At the moment it's the only thing I could think of.

How do I get Entity Framework to only update the Properties modified in the SQL generated?

I am using Entity Framework with the Self-Tracking Entity T4 templates, which by default will generate a SQL Query setting all the properties on the Entity in an UPDATE statement. I only want an UPDATE statement that contains the properties modified.
I modified the T4 Template as specified in the book: Entity Framework Recipes: A Problem-Solution Approach page 503.
I changed to this line in the T4 Template:
OriginalValueMembers originalValueMembers = new OriginalValueMembers(false, metadataWorkspace, ef);
Making the Entity track each property change instead of just tracking that the Entity changed.
And also
context.ObjectStateManager.ChangeObjectState(entity, EntityState.Unchanged);
After making these changes I got the desired result of SQL statement with only the modified values/properties in the UPDATE statement. However, there was a strange side effect. When updating a nullable INT property from null to something other than null, the change of that was ignored by Entity Framework. The Self-Tracking Models show the change in the ChangeTracker with the accurate OriginalValue null, but when Entity Framework tried to generate the UPDATE SQL it did not see that property change if the original value null and the new value is not null. I worked if the original value was not null and value gets changed.
It seems to work ok on a string property going from null to a non-null value, but int? is not working.
Does anyone have any ideas?
If helpful, have found post that fixes this: fix update of nullable column.

Views and Entity Framework

I've created a view in my database which I would like to include in my entity model. However, when I try to update the entity model through VS 2008, a warning message informs me that the TABLE OR VIEW I'm trying to add doesn't have a primary key.
It seems that in order to add a view to the model, this must have a key field! How can I add this view to my model if views are not permitted to have key field, at least in firebird which is the DBMRS I’m using.
Any idea of how to solve this?
There's a great answer to that here: Entity Framework and SQL Server View (see accepted answer: https://stackoverflow.com/a/2715299/53510.)
EF infers a PK for views by combining all non-nullable fields. You can use ISNULL and NULLIF to manipulate the nullability of view columns thereby forcing EF to pick the PK you want.
There is no keys in firebird views. Instead, set one (or more) field as 'not null' with the following command:
update RDB$RELATION_FIELDS set RDB$NULL_FLAG = 1 where (RDB$FIELD_NAME = 'A_FIELD') and (RDB$RELATION_NAME = 'A_VIEW')
Then re-import the database in entity framework.

Entity framework - "Problem in mapping fragments"-error. Help me understand the explanations of this error

Error 3007: Problem in Mapping Fragments starting at lines 186, 205: Non-Primary-Key column(s) [WheelID] are being mapped in both fragments to different conceptual side properties - data inconsistency is possible because the corresponding conceptual side properties can be independently modified.
I found several places on the web describing this error, but I simply don't understand them. (confused smiley goes here)
One
Two
Three
Four
There is something pretty fundamental here, I must be missing. Can you explain it, so that I understand it? Maybe using my real life example below?
Foreign key 1:N Wheels.Id -> Slices.WheelId
I add them to entity framework, and WheelId is not visible in the Slices-entity.
Doing some workaround (deleting the relationship from the db before adding tables to EF - then re-creating it and updating EF) I managed to get the WheelId to stay in Slices, but then I get the error mentioned at the top.
Since Slices.WheelId is an FK, you cannot expose it in your client model, period. There are ways to get the value, though.
var wheelId = someSlice.Wheels.ID;
Update In EF 4 you can do this by using FK Associations instead of independent associations.
Try to remove foreign property column from Entity set using entity model design it will solve your problem
For example
We have two tables one is customer and other one is order, using entity model design we added association between customers and orders when we do this Ado.net entity framework i will add navigation properties to both below tables.
Like
Customer.Orders - Here order is list
Order.Customer
One - Many relation.
So we need to remove property from with name CustomerId[Foreign key column] from Order entity set.
For reference:
http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/2823634f-9dd1-4547-93b5-17bb8a882ac2/
I was able to overcome this problem by the following steps:
right click the designer window
Select 'update model from database'
Select Add AND make sure that the 'Include foreign key columns in the model' checkbox is selected.
click on Finish...
I had set foreign keys up in the database but framework still wasn't pulling them in correctly. So I tried to add the association myself. 
However, when I did this I would get a mapping error. It took me A WHILE but I figured out. What I did was set up the association using the entity toolbox association tool and then you have to double click on the association (1 to many) line and set the primary and foreign key there. Hopefully, this to help others who might have the same problem. I couldn't find the answer anywhere.
I had this problem for quite a different reason, and the message was slightly different; it didn't say "data inconsistency is possible because the corresponding conceptual side properties can be independently modified."
I have a table involved in my model with a binary column where I store image data. I only want this data returned when I need it (performance is a feature), so I split the table using a method similar to this. Later on, I added a property to that table, then updated the model from the database. The wizard added the property to both entity types that refer to the table with the added property. I had to delete it from one of them to solve the error.
I've had this happen because Entity Framework Update wizard mismapped some keys (or did not update?). As a result, some columns were mistakenly labeled as keys, while actual key columns were treated as plain columns.
The solution was to manually open EDMX file, find the entities, and update the keys.
Couldn't get any of the answer to work with EF6. The problem seems to be the framework doesn't import the foreign keys correctly as Associations. My solution was removing foreign keys from the tables, and then manually adding the associations using Entity Framework model, using the following steps: Entity Framework - Add Navigation Property Manually
For LinQ to Entities queries in EF1, my workaround for not having access to the foreign key as a property is with the following code, which does not produce a join query to the associated table:
dbContext.Table1s.FirstOrDefault(c => (int?)c.Table2.Id == null)
i.e, the generated SQL is:
...WHERE ([Extent1].[Table2Id] IS NULL)...
Solution is to allow deleting Rule = Cascade on Sql association.
Same thing as to be done on .edmx model, adding element to
association:
<Association Name="FK_Wheels_Slices">
<End Role="Wheels" Type= "your tipe here" Multiplicity="1">
<OnDelete Action="Cascade" />
</End>
</Association>
I had a table already mapped in EF. I added two more tables which had foreign keys in the previously added table. I then got the 3007 error.
To fix the error I deleted all three tables from the EDMX file, and then re-added them all at once together (via "Update Model from Database..."), instead of in stages.
I checked my Error List window and noticed I had errors in the model. Fixed them and all is well
in my case I solved this error by tick (include foreign key columns in the model)
- update Model from database
- tick (include foreign key columns in the model)
- finish