有没有办法找到有他们的关系中删除的所有实体? [英] Is there a way to find all Entities that have had their relationships deleted?

查看:156
本文介绍了有没有办法找到有他们的关系中删除的所有实体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想不会有我的业务逻辑知道我的数据层和正相反的内部运作。

I am trying to not have my Business Logic know the inner workings of my Data Layer and vica versa.

但实体框架是使这一努力。

But Entity Framework is making that hard. I can insert into a collection (in my Business Layer) without a reference to the ObjectContext:

order.Containers.Add(new Container { ContainerId = containerId, Order = order });

和节省很好,当谈到时间做的SaveChanges()在数据层。

And that saves fine when it comes time to do a SaveChanges() in the Data Layer.

不过,从我需要一个参考ObjectContext的集合删除项目。 (我在这<案例#1 href="http://blogs.msdn.com/b/dsimmons/archive/2010/01/31/deleting-foreign-key-relationships-in-ef4.aspx"相对=nofollow>指南删除EF实体)如果我只是这样做:

But to delete an item from a collection I need a reference to the ObjectContext. (I am case #1 in this guide to deleting EF Entities.) If I just do this:

 delContainers.ForEach(container => order.Containers.Remove(container));

后来,当我打电话的SaveChanges()我得到一个异常告诉我,我需要删除的对象,以及作为参考。

Then when I call SaveChanges() I get an exception telling me that I need to delete the object as well as the reference.

所以,我的选择,我看到它是:

So, my options as I see it are:

  1. 要通过一个委托给我的商业逻辑,将调用实体框架ObjectContext的删除方法。
  2. 或(我希望)找一种方式来获得有他们引用删除了所有的实体和实际删除它们。(前右调用的SaveChanges()在我的数据层。)
  1. To pass a delegate to my Business Logic that will call the Entity Framework ObjectContext Delete method.
  2. Or (I am hoping) find a way to get all entities that have had their reference deleted and actually delete them. (Right before calling SaveChanges() in my data layer.)

有谁知道一个办法做到这一点?

Does anyone know a way to do that?

更新:

我尝试这样做:

// Add an event when Save Changes is called
this.ObjectContext.SavingChanges += OnSavingChanges; 

...

void OnSavingChanges(object sender, EventArgs e)
{
   var objectStateEntries = ObjectContext.ObjectStateManager
                                  .GetObjectStateEntries(EntityState.Deleted);

   foreach (var objectStateEntry in objectStateEntries)
   {
       if (objectStateEntry.IsRelationship)
       {
            // Find some way to delete the related entity
       }
   }
}

不过,即使我删除了一个关系没有,集删除的项目是空的。

But none even though I deleted a relationship, the set of deleted items is empty.

(我想查看的所有项目也和我的关系是不是在那里。很明显,有一些基本的东西,我没有得到有关ObjectStateManager。)

(I tried viewing all the items too and my relationship is not in there. Clearly there is something fundamental that I don't get about ObjectStateManager.)

推荐答案

有关EF正确的解决方案是3点从链接的文章。这意味着传播FK到主要实体为PK为相关实体。这样就形成一种叫<一href="http://stackoverflow.com/questions/4922228/entity-framework-4-delete-object-from-entity-collection/4925040#4925040">identifying关系的自动删除时,它是从父实体删除依赖实体。

The correct solution for EF is point 3. from the linked article. It means propagating FK to principal entity into PK for dependent entity. This will form something called identifying relation which automatically deletes dependent entity when it is removed from the parent entity.

如果你不想改变你的模型,并仍想达到的持久性无知的方式,你也许可以,但它仅适用于<一href="http://stackoverflow.com/questions/5281974/$c$c-first-independent-associations-vs-foreign-key-associations/5282275#5282275">independent协会的。一些初步的实现,它的工作原理至少对于我的简单测试的解决方案:

If you don't want to change your model and still want to achieve that in persistence ignorant way you probably can but it will work only for independent associations. Some initial implementation which works at least for my simple tested solution:

public partial class YourObjectContext
{
    public override int SaveChanges(SaveOptions options)
    {
        foreach (ObjectStateEntry relationEntry in ObjectStateManager
                                             .GetObjectStateEntries(EntityState.Deleted)
                                             .Where(e => e.IsRelationship))
        {
            var entry = GetEntityEntryFromRelation(relationEntry, 0);
            // Find representation of the relation 
            IRelatedEnd relatedEnd = entry.RelationshipManager
                                          .GetAllRelatedEnds()
                                          .First(r => r.RelationshipSet == relationEntry.EntitySet);

            RelationshipType relationshipType = relatedEnd.RelationshipSet.ElementType;
            if (!SkipDeletion(relationshipType))
            {
                // Now we know that model is inconsistent and entity on many side must be deleted
                if (!(relatedEnd is EntityReference)) // related end is many side
                {
                    entry = GetEntityEntryFromRelation(relationEntry, 1);
                }

                if (entry.State != EntityState.Deleted)
                {
                    context.DeleteObject(entry.Entity);
                }
            }
        }

        return base.SaveChanges();
    }

    private ObjectStateEntry GetEntityEntryFromRelation(ObjectStateEntry relationEntry, int index)
    {
        var firstKey = (EntityKey) relationEntry.OriginalValues[index];
        ObjectStateEntry entry = ObjectStateManager.GetObjectStateEntry(firstKey);
        return entry;
    }

    private bool SkipDeletion(RelationshipType relationshipType)
    {
        return
            // Many-to-many
            relationshipType.RelationshipEndMembers.All(
                r => r.RelationshipMultiplicity == RelationshipMultiplicity.Many) ||
            // ZeroOrOne-to-many 
            relationshipType.RelationshipEndMembers.Any(
                r => r.RelationshipMultiplicity == RelationshipMultiplicity.ZeroOrOne);
    }
}

要使它发挥作用的实体必须对动态变化的跟踪启用(所有属性必须是虚拟和实体必须被代理),或者你必须手动调用 DetectChanges

To make it work your entities must be enabled for dynamic change tracking (all properties must be virtual and entity must be proxied) or you must manually call DetectChanges.

在情况外键关联的情况将可能变得更糟,因为你不会找到状态管理器删除任何关系。你将不得不手动跟踪更改集合或钥匙,并比较他们找到的差异(我不知道怎么做,在通用的方式)外键关联恕我直言,需要确定关系。使用FK性质已经意味着你包含额外的持续性依赖到模型。

In case of foreign key associations the situation will be probably much worse because you will not find any deleted relation in the state manager. You will have to track changes to collections or keys manually and compare them to find discrepancies (I'm not sure how to do it in generic way) Foreign key association IMHO requires the identifying relation. Using FK properties already means that you included additional persistence dependency into your model.

这篇关于有没有办法找到有他们的关系中删除的所有实体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆