Working with detached objects is quite tricky.
Anyway, one way is to add a property for the foreign key and handle it (not just add the property). See other answer for details. If you want to work with detached entities I think that this is the best choice. It does not work if you need to work with n-m relationships (HasMany WithMany).
Another solution is this (This works also with n-m relationship)
context.Holders.Attach(holder);
context.Entry(holder).State = EntityState.Modified;
var manager = ((IObjectContextAdapter)context).ObjectContext.ObjectStateManager;
manager.ChangeRelationshipState(holder, holder.Thing, "Thing", EntityState.Added);
context.SaveChanges();
The problem about this solution is that EF generates an update query similar to this
update [Holders]
set [Some] = @p0, [ThingId] = @p1
where (([Id] = @p2) and [ThingId] is null)
@p0 = "Holder updated"
@p1 = 100
@p2 = 200
(look at the where clause)
You have a similar behaviour if you change your update method to this (that is more readable).
var thing = holder.Thing;
holder.Thing = null;
var attachedHolder = context.Holders.Attach(holder);
attachedHolder.Thing = thing;
context.Entry(holder).Property("Some").IsModified = true;
context.SaveChanges();
Also in this case the generated update query is
update [Holders]
set [Some] = @p0, [ThingId] = @p1
where (([Id] = @p2) and [ThingId] is null)
@p0 = "Holder updated"
@p1 = 100
@p2 = 200
So, in both cases you need to know the original Thing (that can be detached). If you know it you can change your code in this way:
var thing = holder.Thing;
holder.Thing = myOldThing; // for example new Thing() {Id = 2} works
var attachedHolder = context.Holders.Attach(holder);
attachedHolder.Thing = thing;
context.Entry(holder).Property("Some").IsModified = true;
context.SaveChanges();
Actually I haven't read this part of EF source code but I that this behaviour think is related to the relationship handler that can manage also n-m relationships (HasMany-WithMany). In this case EF generates also the "support" table for the relationship and the primary key columns is the sum of primary key columns of the two tables. Updating this kind of relationships requires a where on the primary key of the support table.