实体框架,从集合中删除会导致外键异常

时间:2017-03-29 20:14:10

标签: c# entity-framework

我有一个代码优先的EF数据库解决方案。以下是我的模型类:

public class HolidayAllowance
{
    private decimal _taken;

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    [Required]
    public int EmployeeId { get; set; }
    public decimal Allowance { get; set; }
    public virtual ObservableCollection<Holiday>  Holidays { get; set; }

    public decimal Taken
    {
        get { return Holidays?.Sum(x => x.Duration) ?? 0; }
        set { _taken = value; }
    }

    public decimal Remaining => Allowance - Taken;
}

public class Holiday
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public DateTime HolidayStartDay { get; set; }
    public HolidayType HolidayStartDayType { get; set; }
    public decimal Duration { get; set; }
    public int HolidayAllowanceId { get; set; }
}

我的DbContext

public class StaffAndInvoiceManagerDbContext : DbContext
{
    public DbSet<Customer> Customers { get; set; }
    public DbSet<Employee> Employees { get; set; }
    public DbSet<HolidayAllowance> HolidayAllowances { get; set; }
    public DbSet<Note> Notes { get; set; }
    public DbSet<Termination> Terminations { get; set; }
}

我的DataService尝试从holidayAllowance删除假期的方法:

public void DeleteHoliday(Holiday selectedHoliday)
{
   var allowance = _dbContext
       .HolidayAllowances
        .FirstOrDefault(x => x.Id == selectedHoliday.HolidayAllowanceId);

    allowance?
      .Holidays
      .Remove(selectedHoliday);

   _dbContext.SaveChanges();
}

我的ViewModel上调用它的方法:

private void DeleteHoliday()
{
    if (!_messageBoxService.AskYesNoQuestion("Delete Holiday?", "Do you want to delete this holiday?")) return;

    _staffDataService.DeleteHoliday(SelectedHoliday);
    HolidayAllowance.Holidays.Remove(SelectedHoliday);
    RaisePropertyChanged(nameof(HolidayAllowance));
}

问题是,当我尝试从Holiday集合中删除HolidayAllowance.Holidays时,出现以下错误:

  

操作失败:无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性将设置为空值   如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

我不明白为什么会违反FK?我只是想从一个集合中删除。

EF正在生成的数据库表。

enter image description here

我可以执行以下SQL,但不会抛出FK异常。

delete from dbo.Holidays
where Id = 2

它生成的外键如下所示,如果我在SSMS中编写脚本

ALTER TABLE [dbo].[Holidays]  WITH CHECK ADD  CONSTRAINT [FK_dbo.Holidays_dbo.HolidayAllowances_HolidayAllowanceId] 
FOREIGN KEY([HolidayAllowanceId])
REFERENCES [dbo].[HolidayAllowances] ([Id])
GO

ALTER TABLE [dbo].[Holidays] CHECK CONSTRAINT [FK_dbo.Holidays_dbo.HolidayAllowances_HolidayAllowanceId]
GO

我在阅读下面的@Fals评论后,在我的DBContext中尝试了以下内容。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
    modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
    base.OnModelCreating(modelBuilder);
}

我原以为EF会做类似的事吗?仍然没有运气。

1 个答案:

答案 0 :(得分:1)

我已经找到了解决方法,但我不确定它为什么会起作用,或者它是否是正确的方法。无论如何,

_dbContext.Entry(selectedHoliday).State = EntityState.Deleted;
_dbContext.SaveChanges();       

该项目已删除。

我不知道为什么我必须这样做而不只是从它的父母那里删除它