Entity framework 一对一关系中的级联删除

Entity framework 一对一关系中的级联删除,entity-framework,model,ef-fluent-api,cascading-deletes,Entity Framework,Model,Ef Fluent Api,Cascading Deletes,我希望在1:1关系中进行级联删除,其中我将多个实体引用到一个实体。问题是数据库更新时向我抛出一个错误 在表“CategoryArticles”上引入外键约束“FK_dbo.CategoryArticles_dbo.Articles_Article_Id”可能会导致循环或多个级联路径。指定“在删除时不执行操作”或“在更新时不执行操作”,或修改其他外键约束 RoutingSeo实体用于在数据库中存储seo友好url,以备以后使用。我的问题显然是M:N文章和类别之间的关系。有什么办法可以解决这个问题吗

我希望在1:1关系中进行级联删除,其中我将多个实体引用到一个实体。问题是数据库更新时向我抛出一个错误

在表“CategoryArticles”上引入外键约束“FK_dbo.CategoryArticles_dbo.Articles_Article_Id”可能会导致循环或多个级联路径。指定“在删除时不执行操作”或“在更新时不执行操作”,或修改其他外键约束

RoutingSeo
实体用于在数据库中存储
seo友好url
,以备以后使用。我的问题显然是
M:N
文章和
类别
之间的关系。有什么办法可以解决这个问题吗

这是我的模型的实体

public class Article : IEntity<int>
{
    public int Id { get; set; }

    public string Name { get; set; }

    public ICollection<Category> Categories { get; set; }

    [Required]
    public virtual RoutingSeo RoutingSeo { get; set; }
    public int RoutingSeoId { get; set; }

}

public class Category : IEntity<int>
{
    public int Id { get; set; }

    public string Name { get; set; }

    public ICollection<Article> Articles { get; set; }

    [Required]
    public virtual RoutingSeo RoutingSeo { get; set; }
    public int RoutingSeoId { get; set; }
}

public class SpecificProduct : IEntity<int>
{
    public int Id { get; set; }

    public string Name { get; set; }

    [Required]
    public RoutingSeo RoutingSeo { get; set; }        
    public int RoutingSeoId { get; set; }
}

public class RoutingSeo : IEntity<int>
{
    public int Id { get; set; }

    public string SeoRoute { get; set; }

    public Article Article { get; set; }
    public SpecificProduct SpecificProduct { get; set; }
    public Category Category { get; set; }
}
公共类文章:IEntity
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共ICollection类别{get;set;}
[必需]
公共虚拟路由seo RoutingSeo{get;set;}
public int RoutingSeoId{get;set;}
}
公共类类别:公共性
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共ICollection项目{get;set;}
[必需]
公共虚拟路由seo RoutingSeo{get;set;}
public int RoutingSeoId{get;set;}
}
公共类特定产品:通用性
{
公共int Id{get;set;}
公共字符串名称{get;set;}
[必需]
公共路由SEO路由SEO{get;set;}
public int RoutingSeoId{get;set;}
}
公共类路由SEO:安全性
{
公共int Id{get;set;}
公共字符串SeoRoute{get;set;}
公共物品文章{get;set;}
公共特定产品特定产品{get;set;}
公共类别{get;set;}
}
这是我的fluent api代码,我在其中指定了级联删除

modelBuilder.Entity<Article>()
    .HasRequired(x => x.RoutingSeo)
    .WithOptional(x=>x.Article)
    .WillCascadeOnDelete();

modelBuilder.Entity<Category>()
    .HasRequired(x => x.RoutingSeo)
    .WithOptional(x=>x.Category)
    .WillCascadeOnDelete();

modelBuilder.Entity<SpecificProduct>()
    .HasRequired(x => x.RoutingSeo)
    .WithOptional(x=>x.SpecificProduct)
    .WillCascadeOnDelete();
modelBuilder.Entity()
.HasRequired(x=>x.RoutingSeo)
.WithOptional(x=>x.Article)
.WillCascadeOnDelete();
modelBuilder.Entity()
.HasRequired(x=>x.RoutingSeo)
.WithOptional(x=>x.Category)
.WillCascadeOnDelete();
modelBuilder.Entity()
.HasRequired(x=>x.RoutingSeo)
.WithOptional(x=>x.SpecificProduct)
.WillCascadeOnDelete();

你是对的,这是你在
文章
类别
之间的多对多关系:一篇
文章
有零个或多个
类别
,每一个
类别
都可能被零个或多个
文章
使用

如果您删除一篇
文章
,其
类别
将无法自动删除,因为该
类别
可能会被其他
文章
使用,即使它现在未被使用,entity framework也不知道您明天是否要使用它。毕竟,您指定了每个
类别
都可以被零篇或更多的
文章
使用

类似地,如果删除
类别
,entity framework无法自动删除属于该类别的
文章

这与一对多关系不同。例如,如果一本
与其
页面
之间存在一对多关系,那么每本
都有零个或多个
页面
,而每一个
页面
都只属于一本

如果删除
书籍
,则实体框架知道它应该自动删除
书籍
的所有
页面
,这些页面都是带有外键的
书籍ID
。如果实体框架只删除
书籍
,那么我们将有一堆
页面
,外键值指向不存在的
书籍
。所以在一对多关系中,实体框架可以在删除时级联

唉,在多对多中,这是不可能的

好的一面是,您可以删除
类别
的最后一篇
文章
,并保持
类别
的完整性。明天您可以添加一篇新的
文章
,该文章使用该
类别

因此,如果要删除文章,必须手动将其从其使用的“类别”中删除:

多对多遵循标准命名约定:

class Article
{
    public int Id {get; set;}
    // an Article belongs to zero or more Categories:
    public virtual ICollection<Category> Categories {get; set;}
    ...
}
class Category
{
    public int Id {get; set;}
    // a Category is used by zero or more Articles:
    public virtual ICollection<Article> Articles{get; set;}
    ...
}
实体框架将自动执行适当的联接,并从每个类别中删除articleToRemove。但是,这些类别不会被删除

事实上,在内部,Categories表根本没有改变。将从联接表中删除具有Article.Id的所有记录

class MyDbContext : DbContext
{
    public class DbSet<Article> Articles {get; set;}
    public class DbSet<Category> Categories {get; set;}
}
using (var dbContext = new MyDbContext(...))
{
    Article articleToRemove = ...
    dbContext.Articles.Remove(articleToRemove);
    dbContext.SaveChanges();
}