【问题标题】:How can I ensure a parent is deleted when it has no children?当没有孩子时,如何确保删除父母?
【发布时间】:2014-05-15 18:09:18
【问题描述】:

在我的应用程序中,我有一个 1 - many 关系,它将“Slots”与“Adverts”映射起来,这样一个广告就可以添加到多个 slot。

Slot (id, location)
Advert (slot_id, text, url)

但是,当从所有广告位中删除广告时,我也希望将其删除。

我认为最好的方法是在Slot.Advert setter 和Advert.Slots.Remove() 方法中添加一个检查,这样如果要删除最后一个关系,则可以删除广告;

public class Slot
{
    public int Id { get; set; }

    public int? AdvertId { get; set; }

    private Advert _Advert;
    public virtual Advert Advert
    {
        get
        {
            return _Advert;
        }

        set
        {
            if (_Advert != value && _Advert != null && _Advert.Slots.Count == 1)
            {
                // How do I delete the _Advert here? I have no access to the context? :(
            }

            _Advert = value;
        }
    }
}

但是,如上所示,我在setter 中没有“上下文”实例,因此我无法删除广告。

虽然我可以打开一个新的上下文,但这样做

  • 感觉不对
  • 被删除的广告和应用到广告位的新广告不会是事务性的(发生在两个单独的上下文连接中)。

有人知道我有什么选择吗?我在 POCO 领域并使用 Entity Framework 6.1

【问题讨论】:

    标签: c# entity-framework relationship


    【解决方案1】:

    SaveChanges 方法中针对您的上下文执行此操作。

    public override int SaveChanges()
    {
        foreach (var entry in ChangeTracker.Entries<Advert>().Where(e=>e.Entity.Slots.Count()==0))
        {
            entry.State = EntityState.Deleted;
        }
        return base.SaveChanges();
    }
    

    【讨论】:

    • Foreach 用于所有SaveChanges 呼叫??有性能问题吗?
    • SaveChanges 多久调用一次?它正在检查内存中的对象。在任何给定时间有多少Advert 实体被跟踪?我认为这不是问题,但当然您的里程可能会有所不同。
    • @JC:我有点不确定在这种情况下更改跟踪器将如何工作;例如,如果我直接执行slot.Advert = null,这是否会导致Advert 出现在更改跟踪器中(即使我没有专门将其加载到内存中;我使用延迟加载)?
    • 这取决于slot 及其Advert 导航属性最初是如何填充的。如果它来自 LinqToEntities 查询,并且您仍在针对运行查询的上下文进行操作,那么它应该仍然在内存中。延迟加载会将其加载到上下文的内部集合中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-12
    • 1970-01-01
    • 2012-06-13
    • 1970-01-01
    • 2019-02-02
    • 2014-03-02
    • 1970-01-01
    相关资源
    最近更新 更多