I'm migrating from Linq-to-SQL to Entity Framework (4.4), using Database First with a DbContext. I'm wondering whether the following behavior is normal:
using (var e = new AgendaEntities()) {
var store = e.Stores.First();
var office = e.Offices.Create();
office.Store = store; // Set association
Console.WriteLine(office.StoreID); // shows Guid.Empty, expected store.ID!
}
In L2S, setting the Store
association to an entity would also update the StoreID
key. In EF, this doesn't seem to be happening. This is regardless of whether the entities are new or loaded from the context.
When I SaveChanges
, it saves correctly and the StoreID
is updated to match office.ID
, but why does this only happen after the save?
Is there something I'm missing, or am I now supposed to keep foreign keys in sync manually?
Solution Edit:
This is called property fixup, and used to be done automatically by the generated proxies. However, with DbContext
this is no longer the case. According to this Connect issue, this is by design.
Hello, The DbContext template actually doesn't generate classes that will be used as change tracking proxies - just lazy loading proxies (which don't do fix-up). We made this decision because change tracking proxies are complex and have a lot of nuances that can be very confusing to developers. If you want fix-up to occur before SaveChanges you can call myContext.ChangeTracker.DetectChanges. ~EF Team
An alternative is to call DbContext.Entry(entity)
, which will sync up the entity. This is described in this article: Relationships and Navigation Properties under "Synchronizing the changes between the FKs and Navigation properties"
To create Foreign Key, you need to use ForeignKey attribute with specifying the name of the property as parameter. You also need to specify the name of the table which is going to participate in relationship.
You can then configure foreign key properties by using the HasForeignKey method. This method takes a lambda expression that represents the property to be used as the foreign key.
A navigation property is an optional property on an entity type that allows for navigation from one end of an association to the other end. Unlike other properties, navigation properties do not carry data. A navigation property definition includes the following: A name.
No. Entity framework does this for you. Read Relationships and Navigation Properties for more information.
By assigning a new object to a navigation property. The following code creates a relationship between a course and a
department
. If the objects are attached to the context, thecourse
is also added to thedepartment.Courses
collection, and the corresponding foreign key property on the course object is set to the key property value of thedepartment
.
course.Department = department;
But as you observed, this only happens after you call SaveChanges
or one of the other actions mentioned in the "Synchronizing the changes between the FKs and Navigation properties" portion of the document linked above.
If you are using POCO entities without proxies, you must make sure that the DetectChanges method is called to synchronize the related objects in the context. Note, that the following APIs automatically trigger a DetectChanges call.
- DbSet.Add
- DbSet.Find
- DbSet.Remove
- DbSet.Local
- DbContext.SaveChanges
- DbSet.Attach
- DbContext.GetValidationErrors
- DbContext.Entry
- DbChangeTracker.Entries
- Executing a LINQ query against a DbSet
If this is not happening at all, my guess is that you haven't properly defined StoreID
as the foreign key of the navigation property Store
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With