实体框架(EF)代码优先级联删除一对一或零关系

ars*_*ogy 52 c# entity-framework cascading-deletes ef-code-first entity-framework-5

Julie LermanPluralsight"Entity Framework 5入门"课程的"Code First Modeling"部分之后,我创建了两个POCO类,其中包含一对一或零关系:父(User)和可选孩子(UserDetail).

User和UserDetail数据模型图(点击查看).

请注意,图中UserId属性是UserDetail的主键和外键.

相关代码:

public class User
{
    //...

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }

    /* Has a 1:0..1 relationship with UserDetail */
    public virtual UserDetail UserDetail { get; set; }

    //...
}

public class UserDetail
{
    //...

    /* Has a 0..1:1 relationship with User */
    public virtual User User { get; set; }

    [Key, ForeignKey("User")]
    public int UserId { get; set; }

    //...
}

public class EFDbContext : DbContext
{
    public DbSet<User> Users { get; set; }
    //public DbSet<UserDetail> UserDetails { get; set; }  /* Explicit declaration not necessary. Context is aware of UserDetail entity due to 0..1:1 relationship with User */

    public EFDbContext()
    {
        Configuration.ProxyCreationEnabled = true;
        Configuration.LazyLoadingEnabled = true;
    }
}

public class UserRepository : IUserRepository
{
    private EFDbContext _context = new EFDbContext();

    public void Delete(User entity)
    {
        entity = _context.Users.Find(entity.UserId);

        //...

        _context.Users.Remove(entity);
        _context.SaveChanges();

        //...
    }
}
Run Code Online (Sandbox Code Playgroud)

当调用UserRepository类中的Delete()方法时,它不会删除数据库中的用户记录,因为UserDetail中的外键没有启用级联删除.

DELETE语句与REFERENCE约束"FK_dbo.UserDetail_dbo.User_UserId"冲突.

如何使用Entity Framework Code First 启用一对一或零关系的级联删除(以便删除用户自动删除UserDetail)?

hut*_*oid 72

您必须使用流畅的API来执行此操作.

尝试将以下内容添加到您的DbContext:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{   
    modelBuilder.Entity<User>()
        .HasOptional(a => a.UserDetail)
        .WithOptionalDependent()
        .WillCascadeOnDelete(true);
}
Run Code Online (Sandbox Code Playgroud)

  • 使用注释而不是流畅的API无法做到这一点? (25认同)
  • FWIW,这篇文章帮助我了解了将WillCascadeOnDelete()应用于依赖表http://msdn.microsoft.com/en-us/data/jj591620.aspx#RequiredToOptional. (6认同)
  • 正是我需要的.有些人建议[必须]进行级联删除.这确实有效,但当然,只有在实际需要时才有效. (6认同)
  • @Rosdi你读过你上面的评论了吗?如果您不介意fk不可为空,则可以使用[Required]属性. (4认同)

raj*_*azo 5

您还可以通过执行以下操作在应用程序的全局范围内禁用级联删除约定:

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>()
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>()
Run Code Online (Sandbox Code Playgroud)