views:

187

answers:

3

Having two models, Site and Link, where a site has many links, how do I delete a link from inside a method of Site, which doesn't have access to the object context?

I've tried something like:

public void DeleteFirstLink() {
    var link = LinkSet.First();
    LinkSet.Remove(link);
}

but it seems that is not really deleting the link, but breaking the association. Since there's a database constraints it throws this error:

A relationship is being added or deleted from an AssociationSet 'Sites_have_Links'. With cardinality constraints, a corresponding 'Links' must also be added or deleted.

How do I actually delete the link from the database?

A: 

You can't delete anything from the database without an object context. All actions are queued in the state manager of the object context, and those are persisted to the database when you call ObjectContext.SaveChanges(). Without SaveChanges, no DB changes.

Sander Rijken
I'm fine with the actions being queue, I just want to be able to queue them from inside a method in an entity.
J. Pablo Fernández
A: 

First of all, it would be great if you could post a bit more information about your class structures. Does the Site class have an ObjectContext object? Then as a quick solution you could pass it into the delete method and use the context.DeleteObject() method, and call SaveChanges afterwards.

However, as a long-term solution, I will still recommend using the UnitOfWork pattern and I will post the link to the article explaining it again. The implementation might be different, but in general it might solve most of your problems (similar to this one).

The beauty of this approach is that if you use it correctly, you can build a small framework, that you can later reuse in all of your EF projects.

Yakimych
No, the Site entity doesn't have an ObjectContext, why should it?
J. Pablo Fernández
Well, how do you manage the ObjectContext then? Are the Site and Link entities, generated by EF? Do they inherit EntityObject or are you using POCO classes? Do you extend the Site by using a partial class in a separate file?
Yakimych
Yes, Site and Link are entities generated by EF. I suppose they inherit EntityObject, but I would have to check. I have partial classes in separate files for Site, and maybe Link (sorry, not in front of the code right now), but if not, I can make them.
J. Pablo Fernández
A: 

Assuming that your ObjectContext is not alive when you call the DeleteFirstLink() method, you can make it work by spinning up a context inside the method, attaching the Site entity, and then deleting the link:

public void DeleteFirstLink()
{
  using (ProjectEntities db = new ProjectEntities())
  {
    db.AttachTo("[your site EntitySet name - SiteSet?]", this);
    var link = LinkSet.First();
    db.DeleteObject(link);
    LinkSet.Remove(link);
    db.SaveChanges();
  }
}
Yakimych
I'm really curious, does that work? And I don't mean it worked once, I mean it works well and won't explode on edge cases.
J. Pablo Fernández
I don't see any reason why it wouldn't work. You need the ObjectContext to delete an entity, so you spin one up, attach the entity and then call the "DeleteObject" method.What do you mean by "edge cases", btw?
Yakimych