EF Code First +删除标记为已修改的孤立(IsDeleted = 1)

时间:2012-11-03 17:54:39

标签: ef-code-first repository-pattern

我有下一个问题。我的代码上下文+模型:

public class MediaPlanContext : DbContext
{
    public MediaPlanContext() : base(lazyLoading:false) {}

    public DbSet<MediaPlan> MediaPlan { get; set; }
    public DbSet<MovieType> MovieType { get; set; }
    public DbSet<MediaPlanItem> MediaPlanItems { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder
            .Entity<MediaPlanItem>()
            .HasKey(mpi => new {mpi.Id, mpi.MediaPlanId});
        modelBuilder
            .Entity<MediaPlanItem>()
            .Property(mpi => mpi.Id)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        modelBuilder
            .Entity<MediaPlan>()
            .HasMany(mp => mp.MediaPlanItems)
            .WithRequired()
            .HasForeignKey(mpi => mpi.MediaPlanId)
            .WillCascadeOnDelete();
    }        
}

public class MediaPlan : IBaseObject
{
    public virtual ICollection<MediaPlanItem> MediaPlanItems { get; set; }
}

public class MediaPlanItem : IBaseObject
{
    public int MediaPlanId {get;set;}
    public MediaPlan MediaPlan {get;set;} 
}

public interface IBaseObject
{
    public int Id {get;}
    public DateTime DateCreated {get;}
    public DateTime DateModified {get;set;}
}

我还使用存储库来处理带有根对象MediaPlan的对象(IBaseObject-s)。 当我的数据库中的对象被删除时,我将实体(记录)标记为IsDeleted = 1并且我在我的存储库类中有一些逻辑来处理定期删除更新,将EntityState更改为Modified而不是Deleted

下一个代码出现问题:

var rep = new MediaPlanRepository(new MediaPlanContext());
var withItems = rep.GetWithMediaPlanItems();
var m1 = withItems.First();
var mpi1 = m1.MediaPlanItems.First();
m1.MediaPlanItems.Remove(mpi1); // 6 items before remove
// 5 items after remove
rep.SaveChanges();
// 6 items after save changes :(

问题:我可以在saveChanges发生后处理并分离我的IsDeleted = 1实体吗?是解决了我的问题吗?

备注:作为projection加载到根对象的相关实体和Julie在“当这可能无法按预期工作时的情景”段落中说,可能会产生已经被上下文跟踪的实体的问题。

1 个答案:

答案 0 :(得分:0)

代码:

public override int SaveChanges()
{
    var result = base.SaveChanges();
    // AfterSave code
    var isDeletedEntities = EfContext.ChangeTracker
        .Entries()  
        .Select(dbE => new {  
             DBEntity = dbE,  
             BaseObject = (dbE.Entity as IBaseObject)})  
        .Where(dbe => dbe.BaseObject.IsDeleted);  

    foreach (var isDeletedEntity in isDeletedEntities)  
    {  
        isDeletedEntity.DBEntity.State = EntityState.Detached;  
    }
}