开发者

How to delete an associated object in Entity Framework without having access to the object context

开发者 https://www.devze.com 2022-12-17 17:24 出处:网络
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?

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 o开发者_如何学JAVAr 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?


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();
  }
}


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.


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.


  1. To work with entities so the modifications are reflected in the database you MUST ADD/ATTACH these entities in object context (in terms of EF5 in database context) and then use method SaveChanges to commit changes.

  2. Yes, in EF4 to remove a record from phisical SQL table (not a link) you need to use method DeleteObject of object ObjectContext and then SaveChanges, i.e.

    using(ObjectContext context = new ObjectContext)
    {
        /* Find the removed record in object/database context (this will attaches 
         * the record to object/database context)
         * It is recommened to use FirstOrDefault() instead of First() 
         * becase this method can return null if there is no record to delete
         * instead generation of exception in case of using First()
         */
        Link linkToDelete = context.Links.FirstOrDefault(); 
        if(linkToDelete != null) 
        {
            context.DeleteObject(linkToDelete);
            context.SaveChanges();
        }
    }
    
  3. Fortunately now there is EF5 that allows to remove from parent collection but only if relation is one-to-many.

    using(DatabaseContext context = new DatabaseContext)
    {
        Link linkToDelete = context.Links.FirstOrDefault(); 
        if(linkToDelete != null)
        {
            context.Links.Remove(linkToDelete);
            context.SaveChanges();
        }
    }
    
  4. In any case DO NOT forget to call SaveChanges!
0

精彩评论

暂无评论...
验证码 换一张
取 消