Entity Framework - Add Navigation Property Manually - c#

I generated an Entity Framework Model (4.0) from my database. I did not design the database and do not have any control over the schema, but there are a few tables that do not have foreign key constraints defined, but there is an implicit relationship defined.
For example:
I have a table called People that has the following columns:
GenderID
RaceID
There are tables for both Gender and Race but there is no foreign key in the People table.
When I imported the model it did not add Navigation Properties for these relationships. I tried to add it manually but From Role and To Role are disabled. I'm not sure how to add the relationship myself. How do I do this?

Yup - it's not that straightforward.
Here's what you do:
1 - Right click on the designer, Add -> Association
2 - Setup the association and cardinalities (People *..1 Gender, People *..1 Race)
3 - Go into the Model Browser -> Associations
4 - Right click on your newly created associations, click Properties
5 - Here you need to setup the endpoints for the key and cascade options. Make sure you get the endpoints correct. You can also setup a referential constraint here for your implicit navigational property.
6 - Map the navigational property to the relevant tables/fields.
7 - Validate your model, cross your fingers.

I came across this blog post which proposes the following solution, which worked great for me (unfortunately I could not get RPM1984's to work in my situation).
Add an Association via designer background right click contextual menu
Set up your Association (be sure to uncheck creation of foreign key)
Right click on the association and choose Properties
Click on the ... button for Referential Constraint
Set up the relation between the keys within
Verify (from the designer contextual menu)
???
Profit!

Related

ER model generation generates two properties for foreign key

I am learning MVC and I'm creating a project in which I'm Display Information like GSMarena.com phone description. I have created separate tables for Technology, Design, Display. I have used their Primary Key as Foreign key in Products Table but when I generate model in edmx file it creates properties like Design, Design1, Display, Display1 like shown in figure. I'm not able to get the reason behind this as on product create view I need all these properties for product creation.
Why is this happening and how it will effect my project?
With respect to your comment
...when I generate model in edmx file it creates properties like
Design, Design1,...
The Design1 property is the actual table. This means that from the Product table you can access the fields of the related Design table, for example you could type myProduct.Design1.Dimensions to access the Dimensions field from an instance of Products.
The Design property is the actual numeric value of the column Id of the Design table.
I hope this is clear enough.
In the top part of you Product model, you've created fields for Brand, Camera, Connectivity, Design, Display, Hardware and Technology. These are not Foreign Keys
So when you add the associations between the classes, it adds Navigation Properties (which are Foreign Keys) to the table, with the next most appropriate name.
Just remove the fields from the top half of the model and rename the Navigation Properties.

Removing navigation properties from POCO-classes in Entity Framwork

I'm using generated POCO classes and Entity Framework.
In order to make the code less complex I'm trying to remove all navigation properties from the code while still keeping the Foreign Key constraints in the database (navigation properties do more harm than good for us).
If I remove them manually from the POCO-classes I get the following error
The entity type UserEntity is not part of the model for the current context
If I try to remove them from the .edmx-file I get the following error:
Error 3 Error 3015: Problem in mapping fragments starting at lines 479, 562:Foreign key constraint 'fk_StorageContracts_User1' from table StorageContract (OwnerUserID) to table User (ID):: Insufficient mapping: Foreign key must be mapped to some AssociationSet or EntitySets participating in a foreign key association on the conceptual side.
Is there any way to remove navigation properties from POCO-classes without removing the corresponding FK?
I know this is old, but, since there is still no answer, I thought I'd give it a try:
I am still working in EF 4.0, but, following the example to which you referred, you have an xxxModel.tt. If you are willing to tweak that, you can find where it generates the Navigation Properties and change them to be simple auto-properties. I had a similar project where I generated them like this:
public List<NavDataX> NavDataXs
{
get; set;
}
Now, they are still there, but they are null until you explicitly set them. Doing it this way, I did not mess with the EDMX and did not encounter the two errors you mentioned.

One-to-one self-relationship and Entity Framework

I would like to have entity which can have a child (one or zero). This child is same type as parent. I am not sure how to set entity framework becouse I would like to have two navigation properties for every entity. One for navigation to child and one for navigation to parent. Basically it is exactly the same structure as doubly linked list.
I think this table structure should be enough:
int | id | PK
int | id_next | FK
text | data
But how can I create navigation properties for next/prev items? I am able to create only navigation property for next item.
Thanks for help.
You can't. The problem here is that a one-to-one relation has a very specific requirement - FK value must be unique in the whole table. Once the uniqueness is not enforced you can add a second entity pointing to the same parent and you have a one-to-many relation.
To enforce this in a self referencing relation like you described in your example you will place an unique index on the id_next and it will work in SQL server. The problem is that entity framework doesn't support unique keys. Because of that entity framework is only able to build one-to-one relations between two different entity types where FK in the dependent the entity type is also its PK (the only way how to force FK to be unique) = both entities has same PK value. This cannot work with a self referencing relation because you cannot have two same PK values in one table.
You can do this in EF4 by specifying a 0..1 -> 0..1 relationship on the entity. Name one of the navigation properties "Previous" and the other "Next". This will create a hidden field on the underlying DB.
I haven't thoroughly tested this approach but it seemed to work when I created the database script.
Research Tree structures in the Entity Framework. You basically want a vertical tree (i.e. one branch). The framework won't enforce only one branch, but you can manage that in your business logic.

remove foreign key property cause an exception

I don't want to use foreign key association to CompanyType (member that will hold the foreign key id) but prefer to use navigation property. So I removed the CompanyTypeId.
I get this exception that relates the relationship between entity Company and CompanyType:
Error 5: The element 'Principal' in
namespace
'http://schemas.microsoft.com/ado/2008/09/edm'
has incomplete content. List of
possible elements expected:
'PropertyRef' in namespace
'http://schemas.microsoft.com/ado/2008/09/edm'.
How can I remove those id's from the POCOs without getting the exception?
This is the difference between Foreign key association and Independent association. Both associations use navigation properties but only Foreign key association uses FK property as well. You can either remove them globally as #Robbie mentioned or you can change the type manually for selected relation.
Select the relation in entity framework designer
In properties remove Referential constraints
Go to Mapping window and map the relation
Here is the screen shot from one of my testing application with one-to-many relation between Order and OrderLine entities:
As you can see there is no OrderId in the OrderLine entity and referential constraints of the relation are empty. Also mapping of the relation is specified.
BUT you can't never remove Id from CompanyType. Ids (PKs) are mandatory. You can only change its accessibility in its properties.
When you imported in your Model from your DB you are asked if you want to:
"Include Foreign key columns in the model"
you need to switch this off.

Self-Referencing FK Generating Strangly

In the screenshot below is an Entity (URL) in my model. The ParentId field is a self-referencing FK (points to Url.Id). You can see this navigation at the bottom of the screenshot.
In my SQL and my DB, which I generate the EDMX from, the self-referencing FK is called FK_Urls_Parent:
-- Creating foreign key on [ParentId] in table 'Urls'
ALTER TABLE [Urls]
ADD CONSTRAINT [FK_Urls_Parent]
FOREIGN KEY ([ParentId])
REFERENCES [Urls]
([Id])
ON DELETE NO ACTION ON UPDATE NO ACTION;
My questions are:
Why did EF generate Urls1 and Url1 just from that one FK? Url1 is a 0 or 1 property that is 'FromRole' Urls1. Urls1 is 'FromRole' Urls 'ToRole' Urls1. It seems like EF is making a navigation property that is the exact same as Url table. Why would it do this and can I do something to make it just generate the one, desired Navigation property: Urls1?
Okay, so not quite as important, but can I control the name of the Navigation property based on the FK name or something in the DB? I hate that it names it 'Url1'. I would prefer 'Parent', but don't want to have to manually change it in the designer every time I regenerate the model.
Thanks.
It is modeling both sides of the relationship. In other words, one of the properties will be the entry being pointed to by this entry's ParentId. The other will be the entry(s) whose ParentId field points to this entry. You can disable one side in the relationship properties, or rename them to make sense. Such as, for instance, ParentUrl and ChildUrls.
I'm not 100% certain how to get to the property relation dialog without opening the program myself, which I can't right now. I do know for me it appears in the (by default) bottom-right properties window when the link is selected.
As far as making this change somehow permanent across model regenerations, I know of no way to do this. Hopefully someone else will know, because it would save me a lot of time too!

Categories