C# 同时插入时,EntityFramework在更新之前删除

C# 同时插入时,EntityFramework在更新之前删除,c#,sql,.net,entity-framework,entity-framework-6,C#,Sql,.net,Entity Framework,Entity Framework 6,在单个SaveChanges中尝试(可能做得太多)时,我遇到了外键错误 基本上,我有以下3个poco实体 public class ClinicianAvailability { public int ClinicianAvailabilityId { get; set; } } public class SurgicalBooking { public int SurgicalBookingId public

在单个SaveChanges中尝试(可能做得太多)时,我遇到了外键错误

基本上,我有以下3个poco实体

    public class ClinicianAvailability
    {
        public int ClinicianAvailabilityId { get; set; }
    }

 public class SurgicalBooking
    {
        public int SurgicalBookingId
        public int? ClinicianAvailabilityId { get; set; }
        public bool IsAdhoc { get; set; }

        public virtual TheatreBooking TheatreBooking { get; set; }
        public virtual ClinicianAvailability ClinicianAvailability { get; set; }
    }

    public class TheatreBooking
    {
        public int TheatreBookingId {get;set;}

        public virtual SurgicalBooking SurgicalBooking { get; set; }
        public virtual ClinicianAvailability ClinicianAvailability { get; private set; }
    }
我基本上是想删除一位临床医生,他在手术预约上有外键。但与此同时,他试图在手术预约上设置一个新的剧场

像这样:

var entity = _clinicianAvailabilityRepository.Find(resourceAvailabilityId);
    var surgStub = surgicalBookingRepository.CreateStub(bookingData.ScheduleId);
    surgStub.IsAdhoc = true;
    surgStub.ClinicianAvailabilityId = null;
surgicalBookingRepository.SetModified(surgStub, new Expression<Func<SurgicalBooking, object>>[] { x => x.IsAdhoc, x => x.ClinicianAvailabilityId });

    theatreBookingRepository.Add( new TheatreBooking
    {
                                    TheatreBooking Id = theatreBookingRepository.GetNewTempKey(),
                                    TheatreId = associatedTheatreId.Value,                           
                                    SurgicalBooking = surgStub
                                });
                                theatreBookingRepository.Add(TheatreBooking);
_clinicianAvailabilityRepository.Remove(entity);
_clinicianAvailabilityRepository.UnitOfWork.SaveChanges();
var entity=\u clinicianAvailabilityRepository.Find(resourceAvailabilityId);
var surgStub=surgicalBookingRepository.CreateStub(bookingData.ScheduleId);
surgStub.IsAdhoc=true;
surgStub.ClinicianAvailabilityId=null;
SetModified(surgStub,新表达式[]{x=>x.IsAdhoc,x=>x.ClinicianAvailabilityId});
剧院预订位置。添加(新剧院预订)
{
剧院预订Id=剧院预订位置。GetNewTempKey(),
剧院ID=关联的剧院ID.Value,
手术预约
});
添加(剧场预订);
_临床医生可用性报告。删除(实体);
_Clinician Availability repository.UnitOfWork.SaveChanges();
所以基本上在做了这件事之后,我在ClinicalianAvailabilityID的外科预约外键上得到了一个外键错误。如果我去掉剧场预订的添加,它会按照正确的顺序更新手术预订,然后删除。但在添加剧院预订时,它尝试先删除,然后失败。有什么帮助吗?我试着尽可能地简化它,但它有点复杂。我尽量不做多次保存更改或将其全部放在单个事务中,因为更改所有这些代码将需要大量的返工


我查看了ChangeTracker,所有项目似乎都是按正确的顺序出现的,但没有按正确的顺序出现。

我尝试用以下代码复制错误,但成功完成:

    static void CreateAndSeedDatabase()
    {
        Context context = new Context();
        ClinicianAvailability cAvail = new ClinicianAvailability() { };
        SurgicalBooking sBooking = new SurgicalBooking() { IsAdhoc = true, ClinicianAvailability = cAvail };
        context.SurgicalBookings.Add(sBooking);
        context.SaveChanges();
    }

    static void DeleteUpdateInsert()
    {
        Context context = new Context();
        ClinicianAvailability cAvail = context.ClinicianAvailabilitys.Find(1);
        SurgicalBooking sBooking = context.SurgicalBookings.Find(1);
        sBooking.IsAdhoc = false;
        sBooking.ClinicianAvailability = null;
        TheatreBooking tBooking = new TheatreBooking(){SurgicalBooking = sBooking};
        context.TheatreBookings.Add(tBooking);
        context.ClinicianAvailabilitys.Remove(cAvail);
        context.SaveChanges();
    }
上下文类:

public class Context : DbContext
{
    public Context()
    {
        Database.SetInitializer<Context>(new CreateDatabaseIfNotExists<Context>());
        Database.Initialize(true);
    }

    public DbSet<ClinicianAvailability> ClinicianAvailabilitys { get; set; }
    public DbSet<SurgicalBooking> SurgicalBookings { get; set; }
    public DbSet<TheatreBooking> TheatreBookings { get; set; }
}

我尝试用以下代码复制错误,但成功完成:

    static void CreateAndSeedDatabase()
    {
        Context context = new Context();
        ClinicianAvailability cAvail = new ClinicianAvailability() { };
        SurgicalBooking sBooking = new SurgicalBooking() { IsAdhoc = true, ClinicianAvailability = cAvail };
        context.SurgicalBookings.Add(sBooking);
        context.SaveChanges();
    }

    static void DeleteUpdateInsert()
    {
        Context context = new Context();
        ClinicianAvailability cAvail = context.ClinicianAvailabilitys.Find(1);
        SurgicalBooking sBooking = context.SurgicalBookings.Find(1);
        sBooking.IsAdhoc = false;
        sBooking.ClinicianAvailability = null;
        TheatreBooking tBooking = new TheatreBooking(){SurgicalBooking = sBooking};
        context.TheatreBookings.Add(tBooking);
        context.ClinicianAvailabilitys.Remove(cAvail);
        context.SaveChanges();
    }
上下文类:

public class Context : DbContext
{
    public Context()
    {
        Database.SetInitializer<Context>(new CreateDatabaseIfNotExists<Context>());
        Database.Initialize(true);
    }

    public DbSet<ClinicianAvailability> ClinicianAvailabilitys { get; set; }
    public DbSet<SurgicalBooking> SurgicalBookings { get; set; }
    public DbSet<TheatreBooking> TheatreBookings { get; set; }
}

检查删除顺序,首先删除引用外键的表,然后仅删除主表数据,检查是否有更多外键引用如果子项附加到上下文,EF将为每个附加的子项生成delete语句,然后为父项生成delete语句(因为Remove确实将它们全部标记为已删除)这里您将得到详细的解释检查删除顺序,首先删除引用外键的表,然后仅删除主表数据,检查是否有更多外键引用如果子项附加到上下文,EF将为每个附加的子项生成delete语句,然后为父项生成delete语句(因为Remove没有将它们全部标记为已删除)你会在这里得到详细的解释谢谢,我会看一看并尝试复制我的场景谢谢你是正确的它应该可以工作。我发现问题在于我正在使用的SetModified方法,它覆盖了它应该做的事情,因为我不能在剧院预订复杂实体上这样做。我正在尝试这样做为了避免更多的查询,我已经将其更改为进行适当的查找,所有内容都得到了很好的跟踪。感谢您的帮助。谢谢,我将查看并尝试复制我的场景。谢谢您的正确性,它应该可以工作。我发现问题在于我使用的SetModified方法,它覆盖了它应该执行的操作,因为我无法在剧院预订复杂实体上执行此操作。我尝试执行此操作是为了避免更多查询,后来我将其更改为执行适当的查找,并且所有内容都得到了很好的跟踪。感谢您的帮助。