Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 一对零或一关系的实体框架(EF)代码优先级联删除_C#_Entity Framework_Ef Code First_Entity Framework 5_Cascading Deletes - Fatal编程技术网

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

C# 一对零或一关系的实体框架(EF)代码优先级联删除,c#,entity-framework,ef-code-first,entity-framework-5,cascading-deletes,C#,Entity Framework,Ef Code First,Entity Framework 5,Cascading Deletes,在的“代码优先建模”部分之后,我创建了两个具有一对零或一对一关系的POCO类:一个父类(用户)和一个可选的子类(UserDetail) 请注意,在图中,UserId属性是UserDetail的主键和外键 相关代码: public class User { //... [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int UserId { get; set; } /

在的“代码优先建模”部分之后,我创建了两个具有一对零或一对一关系的POCO类:一个父类(用户)和一个可选的子类(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();

        //...
    }
}
公共类用户
{
//...
[关键]
[数据库生成(DatabaseGeneratedOption.Identity)]
public int UserId{get;set;}
/*与UserDetail具有1:0..1关系*/
公共虚拟用户详细信息用户详细信息{get;set;}
//...
}
公共类用户详细信息
{
//...
/*与用户的关系为0..1:1*/
公共虚拟用户用户{get;set;}
[密钥,外国密钥(“用户”)]
public int UserId{get;set;}
//...
}
公共类EFDbContext:DbContext
{
公共数据库集用户{get;set;}
//公共DbSet UserDetails{get;set;}/*不需要显式声明。由于与用户的关系为0..1:1,上下文知道UserDetail实体*/
公共EFDbContext()
{
Configuration.ProxyCreationEnabled=true;
Configuration.LazyLoadingEnabled=true;
}
}
公共类UserRepository:IUserRepository
{
私有EFDbContext_context=新EFDbContext();
公共作废删除(用户实体)
{
实体=_context.Users.Find(entity.UserId);
//...
_context.Users.Remove(实体);
_SaveChanges();
//...
}
}
调用UserRepository类中的Delete()方法时,它不会删除数据库中的用户记录,因为UserDetail中的外键未启用级联删除

DELETE语句与引用约束“FK_dbo.UserDetail_dbo.User_UserId”冲突


您如何首先使用实体框架代码为一对零或一关系启用级联删除(这样删除用户会自动删除用户详细信息)?

您必须使用fluent API才能做到这一点

尝试将以下内容添加到
DbContext

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{   
    modelBuilder.Entity<User>()
        .HasOptional(a => a.UserDetail)
        .WithOptionalDependent()
        .WillCascadeOnDelete(true);
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{   
modelBuilder.Entity()
.has可选(a=>a.UserDetail)
.WithOptionalDependent()
.WillCascadeOnDelete(真);
}

这个代码对我很有用

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<UserDetail>()
            .HasRequired(d => d.User)
            .WithOptional(u => u.UserDetail)
            .WillCascadeOnDelete(true);
    }
而且效果很好。当我第一次使用

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

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

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

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

WillCascadeOnDelete()就是这样做的,尽管我必须将它应用于依赖表(UserDetail),而不是关系中的主体(User)。此外,我还删除了UserDetail类中UserId属性上的Key和ForeignKey数据注释。非常感谢你!FWIW,这篇文章帮助我获得了将WillCascadeOnDelete()应用于依赖表的想法。这正是我所需要的。有些人建议级联删除[Required]。这确实有效,但当然,只有在实际需要的情况下才有效。使用注释而不是fluent API无法做到这一点?@Rosdi您是否阅读了您上面的评论?如果您不介意fk不能为空,可以使用[Required]属性。这节省了我很多时间
AddForeignKey("User", "UserDetail_UserId", "UserDetail", "UserId", cascadeDelete: true); 
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>()
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>()