防止导航属性插入

本文关键字:插入 属性 导航 | 更新日期: 2023-09-27 18:05:36

我有一个实体A用作另一个实体b的导航属性,我想控制实体A的插入,这意味着每当我插入A时,我必须执行其他检查并更新其他实体。
但是当我插入B类型的实体时,它会自动插入连接的A实体,而不需要我需要的额外检查和更新。

我该如何解决这个问题?

我决定按照建议使用这个答案。但是在OnBeforeInsert()中,我可能会添加一个新的实体到上下文,他们的OnBeforeInsert()不会被调用,因为在var changedEntities = ChangeTracker.Entries();被调用的时候,新的实体还不存在。
我怎么解决这个问题?

防止导航属性插入

EF有很少的扩展点。所以有时候很难定制。

这个答案是我上一个答案的延伸

public abstract class Entity
{
    public virtual void OnBeforeInsert(){}
    public virtual void OnBeforeUpdate(){}
}
public class Category : Entity
{
    public string Name { get; set; }
    public string UrlName{ get; set; }
    public override void OnBeforeInsert()
    {
       //ur logic
    }
}

然后在你的DbContext班订阅ObjectStateManagerObjectStateManagerChanged事件。

public class MyContext : DbContext
{
    public override int SaveChanges()
    {
        //intercept entity changes
        UnderlyingObjectContext.ObjectStateManager.ObjectStateManagerChanged 
           += OnObjectStateManagerChanged;
        var changedEntities = ChangeTracker.Entries();
        foreach (var changedEntity in changedEntities)
        {
            if (changedEntity.Entity is Entity)
            {
                var entity = (Entity)changedEntity.Entity;
                switch (changedEntity.State)
                {
                    case EntityState.Added:
                        entity.OnBeforeInsert();
                        break;
                    case EntityState.Modified:
                        entity.OnBeforeUpdate();
                        break;
                }
            }
        }
        return base.SaveChanges();
    }
    ObjectContext UnderlyingObjectContext
    {
         get
         {
              return ((IObjectContextAdapter)this).ObjectContext;
         }
    }
    void OnObjectStateManagerChanged(object sender, CollectionChangeEventArgs e)
    {
        if (e.Action == CollectionChangeAction.Add)
        {
             //not all added entities are new
             if (UnderlyingObjectContext.ObjectStateManager
               .GetObjectStateEntry(e.Element).State == EntityState.Added)
             {
                   if (e.Element is Entity)
                   {
                       ((Entity)e.Element).OnBeforeInsert();
                   }
             }
        }
     }
}

如果你使用的是EF 4.0,你需要相应地定制这个