How to find out which property is used as a Foreign Key between two entities in code first approach - entity-framework

I'm using Entity Framework 5, code first approach. As there's no built in support for updating child entities in disconnected scenario, I'm building my own mechanism to do that. At some point I need to get the property of an entity with which it has a Foreign Key relationship with another (principal) entity. I've tried to get access to CSpace through
((IObjectContextAdapter)dbContext).ObjectContext.MetadataWorkspace.GetItems<MyEntity>(System.Data.Entity.Core.Metadata.Edm.DataSpace.CSpace)
but here I got a warning that said there's no implicit conversion between MyEntity and System.Data.Entity.Core.Metadata.Edm.GlobalItem.
I can't look for a property that has Foreign Key attribute because in most of my entities I use EF convention to get foreign keys automatically. So how one would go about finding which property is used for foreign key relationship.

Thanks to #octavioccl's post I was able to do what I want. So I was in the right path to look inside ObjectContext.

Related

Entity Framework Core: how to 'wipe and replace' bridge table?

Imagine we have a many-to-many relationship (e.g. Product and Category where one product can be in many categories and vice versa). They are identified through a composite key (ProductId / CategoryId). How do we update this bridge table in Entity Framework Core when we want to persist the changes to the Product aggregate?
In Entity Framework 6, I'd simply wipe out all related data for that product in the bridge table and then re-populate them. This simplifies life as we don't need to manually synchronize changes (inserts, updates, deletes). Just wipe and replace.
How do we do this in Entity Framework Core? Here's what I tried:
context.ProductCategories.RemoveRange(product.Categories);
context.ProductCategories.AddRange(updatedProductCategories);
This results in an exception due to duplicate composite key:
InvalidOperationException: The instance of entity type 'ProductCategory' cannot be tracked because another instance of this
type with the same key is already being tracked. When adding new
entities, for most key types a unique temporary key value will be
created if no key is set (i.e. if the key property is assigned the
default value for its type). If you are explicitly setting key values
for new entities, ensure they do not collide with existing entities or
temporary values generated for other new entities. When attaching
existing entities, ensure that only one entity instance with a given
key value is attached to the context.
How do we remove a composite key entity from the context so that we can add another one?
The only way I got this to work so far is to synchronize all changes (deletes, updates, inserts), but it would be much simpler to just wipe and replace.

Entity Framework Model first: adding an association without creating foreign key properties?

I'm playing with the Entity Framework model designer, and I've got a question about creating entity associations:
In the "create association" dialog, when I create a 1:many association, it offers this checkbox:
"Add foreign key properties to the [entityname] entity"
I've been checking this box and I get results that are expected and make sense to me: Clicking the navigation property in the diagram highlights the related field in both entities that tie them together.
But, what would it mean not to check this box? I've tried this, and I then see no place in the entity to store a reference to the parent table's primary id. Am I correct that the navigation properties don't store any data in the database? If so, how could this work? Am I, perhaps, expected to manually map the navigation property to an Int32 field on the entity?
Associations represent relationship between entities. In the database (relational model) these relations are modeled by using foreign keys and - in the case of many-to-many - a join table. In the object model relations are typically modeled as references to the related object (in EF they are often referred to as Navigation Properties). The problem arises when you need to create or modify a relationship in the object model - you always need to have a reference of the related object you would like to set. In a pure object model this usually is not a problem but in case of ORM it means that if you don't have the related entity you need to send a query to the database to get the object to be able to set the reference to. However oftentimes - even if you don't have the related entity - you know the Id of the related entity. So, if the foreign key properties were exposed (and handled) in your object model you could create or modify a relationship without having to send additional queries to the database. This is what the checkbox is about. If you check it your entities will have (extraneous from object model perspective) properties mapped to foreign key columns in the database which you can use to manipulate relationships.

EF entity without a public key

I want to create an entity in EF without a public key. The backing table has got a non-unique clustered key, but the data in the table conceptually doesn't have a unique primary key it can use.
It looks like EF really doesn't like this. Is there any way of getting EF to accept that the table has no primary key and make it work with it anyway, with no performance hit? I don't care if the result is read-only.
As I understand it, as the Entity Framework is based on the Domain Driven Design concept of Entities, each Entity by definition must have a unique identifier. If the concept which the data in your table represents does not conceptually have a unique identifier then it is not an Entity, in the sense intended by the framework.
With this in mind I'd define a Stored Procedure, make it available through my object context, then make the objects encapsulating this data available via a class which lazy-loads the data, manually maps it into the objects you're using and presents it in a read-only manner.
You may also be able to accomplish this by exposing a view and then mapping your entity to the view.

DbContext's ChangeTracker problem

I have a codefirst EF-4.1 based program. The user gets a context and can modify some properties. When the user is done, I do a quick
ChangeTracker.Entries().Any(e => e.State != EntityState.Unchanged);
to determine if a SaveChanges() is required or not. If I do a 'SaveChanges()' call, the changes that have made are persisted to the database.
This works for some properties, and doesn't work for others. Specifically it seems to work with simple types (floats), and with collection hierarchies(ObservableCollections).
Am I doing something wrong?
Yes this is a problem. Some relations are not tracked by DbChangeTracker. There is difference between Independent association and Foreign key association. Changes to relation are tracked in case of:
One-to-one relation which is always Foreign key association in EFv4+
One-to-many relation with Foreign key association - you should set up foreign key property
Changes to relation are not tracked in case of:
One-to-many relation with Independent association
Many-to-many relation which is always Independent association
Not tracked for Independent association is not correct naming. These changes are tracked but DbChangeTracker does not expose access to these changes! You must convert DbContext to ObjectContext and use ObjectStateManager to get access to ObjectStateEntries representing independent associations.
In this case the easiest thing is simply call SaveChanges always. It will not execute any DB commands if no data need to be saved.

Composite DB keys with Entity Framework 4.0

The re-design for a large database at our company makes extensive use of composite primary keys on the database.
Forgetting performance impacts, will this cause any difficulties when working with this db in Entity Framework 4.0? The database structure is unlikely to change and I'm not looking for "philosophical" debate but what are the practical impacts?
According to Jeremy Miller, "Composite key make any kind of Object/Relational mapping and persistance in general harder." but he doesn't really say why. Is this relavent to how Entity Framework 4.0 handles keys?
No, EF4 supports composite keys just fine.
The problem is a table with a surrogate key and composite keys. You can only set a single key on each model; that key can have multiple fields, but you can only have one from the designer standpoint. Not sure about manually editing xml or code only mapping.
You can set a field as an Identity and not a key if you need a composite and surrogate key on the same table. The Identity ( Id ) field won't be used by the ObjectContext or ObjectStateTracker but will increment and be queryable just fine though.
I have had problems with EF4 and composite keys. It doesn't support columns being used as components in more than one key in a join table.
See my previous question Mapping composite foreign keys in a many-many relationship in Entity Framework for more details. The nuts of it is that when you have a join table (describing a many-many relationship) where both of the relationships use a common key, you'll get an error like
Error 3021: Problem in mapping
fragments...: Each of the following
columns in table PageView is mapped to
multiple conceptual side properties:
PageView.Version is mapped to
(PageView_Association.View.Version,
PageView_Association.Page.Version)
The only way around it was to duplicate the column which defeats the purpose of having it there at all.
Good luck!