简体   繁体   English

如何在不访问对象上下文的情况下删除Entity Framework中的关联对象

[英]How to delete an associated object in Entity Framework without having 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 or deleted from an AssociationSet 'Sites_have_Links'. 正在从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: 假设在调用DeleteFirstLink()方法时ObjectContext没有处于活动状态,则可以通过在方法内部旋转上下文,附加Site实体,然后删除链接来使其工作:

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();
  }
}
  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. 要使用实体,以便使修改反映在数据库中,您必须在对象上下文中(根据数据库上下文中的EF5) 添加/附加这些实体,然后使用方法SaveChanges提交更改。

  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 , ie 是的,在EF4中,要从物理SQL表(不是链接)中删除一条记录,您需要使用对象ObjectContext的 DeleteObject方法,然后使用SaveChanges ,即

     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 . 幸运的是,现在有EF5允许从父集合中删除,但前提是关系是一对多的

     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! 无论如何,请不要忘记调用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() . 所有操作都在对象上下文的状态管理器中排队,并且在您调用ObjectContext.SaveChanges()时将这些操作持久化到数据库中。 Without SaveChanges, no DB changes. 没有SaveChanges,就不会更改数据库。

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? Site类是否具有ObjectContext对象? Then as a quick solution you could pass it into the delete method and use the context.DeleteObject() method, and call SaveChanges afterwards. 然后,作为快速解决方案,您可以将其传递到delete方法中,并使用context.DeleteObject()方法,然后再调用SaveChanges。

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. 但是,作为长期解决方案,我仍然建议使用UnitOfWork模式,并且将链接发布到再次解释它的文章上 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. 这种方法的优点在于,如果正确使用它,则可以构建一个小的框架,以后可以在所有EF项目中重用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM