实体框架(EF)的代码,首先级联删除一个到零或一对一的关系实体框架(EF)的代码,首先级联删除一个到

2019-05-08 16:28发布

在的“代码优先模型”一节继Pluralsight“入门与实体框架5”由朱莉·勒曼当然 ,我创建了两个POCO类有一到零或一对一的关系:父(用户)和一个可选孩子(UserDetail)。

用户和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();

        //...
    }
}

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

DELETE语句冲突与基准约束“FK_dbo.UserDetail_dbo.User_UserId”。

你将如何实现级联删除一到零或一对一的关系使用实体框架代码优先(以便删除用户将自动删除UserDetail)?

Answer 1:

你将不得不使用流畅的API来做到这一点。

尝试添加以下到您DbContext

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


Answer 2:

此代码为我工作

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<UserDetail>()
            .HasRequired(d => d.User)
            .WithOptional(u => u.UserDetail)
            .WillCascadeOnDelete(true);
    }

迁移代码为:

public override void Up()
    {
        AddForeignKey("UserDetail", "UserId", "User", "UserId", cascadeDelete: true);
    }

它工作得很好。 当我第一次使用

modelBuilder.Entity<User>()
    .HasOptional(a => a.UserDetail)
    .WithOptionalDependent()
    .WillCascadeOnDelete(true);

迁移代码为:

AddForeignKey("User", "UserDetail_UserId", "UserDetail", "UserId", cascadeDelete: true); 

但它不匹配任何可用的两个重载的(在6的EntityFramework)



Answer 3:

您也可以禁用级联在做这个应用程序的全球范围内删除约定:

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>()
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>()


文章来源: Entity Framework (EF) Code First Cascade Delete for One-to-Zero-or-One relationship