58

在Julie Lerman 的 Pluralsight“Entity Framework 5 入门”课程的“代码优先建模”部分之后,我创建了两个具有一对零或一关系的 POCO 类:一个父级(用户)和一个可选的孩子(用户详细信息)。

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();

        //...
    }
}

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

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

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

4

3 回答 3

75

您将不得不使用 fluent API 来执行此操作。

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

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{   
    modelBuilder.Entity<User>()
        .HasOptional(a => a.UserDetail)
        .WithOptionalDependent()
        .WillCascadeOnDelete(true);
}
于 2013-07-05T11:34:25.660 回答
6

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

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>()
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>()
于 2018-07-11T02:03:26.993 回答
3

这段代码对我有用

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); 

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

于 2016-11-09T00:29:57.427 回答