2017-11-13 2 views
0

1 : 1 관계에서 계단식 삭제를하고 싶습니다. 여기서 여러 항목을 하나씩 참조합니다. 문제는 나에게 사이클 또는 여러 개의 계단식 경로를 일으킬 수 테이블 'CategoryArticles'에 FOREIGN KEY 제약 조건 'FK_dbo.CategoryArticles_dbo.Articles_Article_Id'을 소개 데이터베이스 업데이트1 : 1 관계에서 계단식 삭제

에 오류가 발생합니다. NO DELETE NO ACTION 또는 UP UP NO NO ACTION을 지정하거나 다른 FOREIGN KEY 제약 조건을 수정하십시오.

RoutingSeo 엔티티는 나중에 사용하기 위해 데이터베이스에 seo friendly url을 저장하기위한 것입니다. 내 문제는 ArticleCategory 사이의 명확한 M:N 관계입니다. 이 문제를 어떻게 해결할 수 있습니까? 여기

, 그것은 당신의 다 대다 관계 배는

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

답변

1

자네 말이 맞아입니다

다음
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; } 
} 

내가 캐스케이드 지정 나의 유창한 API 코드가 삭제되어 내 모델 내 엔터티 ArticleCategory 사이 : Article 중 하나 이상은 Categories이며, 모든 Category은 0 이상으로 사용할 수 있습니다. Articles.

당신이 Article을 삭제하면, 그것 Category 다른 Articles에 의해 사용될 수 있기 때문에 Categories은 자동으로 삭제 될 수없고, 그것이 지금 사용하지 않는 경우에도, 엔티티 프레임 워크는 당신이 여부를 알 수 없습니다 내일 사용하십시오. 결국 모든 Category0으로 이상 Articles으로 사용될 수 있습니다.

마찬가지로, Category을 제거하면 엔티티 프레임 워크가이 카테고리에 속한 Articles을 자동으로 제거 할 수 없습니다.

이것은 일대 다 관계와 다릅니다. 예를 들어 BookPages의 일대 다 관계가있는 경우 Book은 모두 Pages이고은 정확히 Book에 속합니다. 당신이 Book을 제거하면

는 다음 엔티티 프레임 워크는 자동으로 외래 키 BookId 모든 Pages이다 이는 Book의 모든 Pages을 제거해야합니다 것을 알고있다. Entity Framework가 Book 만 제거하면 외래 키 값이 Book을 가리키는 Pages이라는 무리가 생깁니다. 따라서 일대 다 관계에서 엔티티 프레임 워크는 삭제를 계단식으로 처리 할 수 ​​있습니다.

아아, 많은 - 대다수에서 이것은 불가능합니다.

밝은면에서 Category의 마지막 Article을 삭제하고 Category을 그대로 유지할 수 있다는 장점이 있습니다. 내일 Category을 사용하는 새 Article을 추가 할 수 있습니다.

대다 다음과 같은 표준 명명 규칙 :

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;} 
    ... 
} 

당신이 기사를 제거하려면

그래서, 당신은 수동으로 사용하는 'Categories`에서 제거해야 ICollections 가상을 선언하는 것을 잊지 마십시오!

class MyDbContext : DbContext 
{ 
    public class DbSet<Article> Articles {get; set;} 
    public class DbSet<Category> Categories {get; set;} 
} 

당신은 접합 테이블을 언급하지 않아도은 엔티티 프레임 워크는 당신을 위해 자동으로 만들 것입니다,하지만 당신은 당신이 Articles을 원하는 경우 자신의 Categories, 또는 Categories과 조인을 사용하지 않습니다 Articles과 함께 ICollections

참고 : 범주가 예상되는 복수형이 아니므로 엔티티 프레임 워크에 적절한 테이블 이름을 지정해야합니다. 이 질문의 범위를 벗어났습니다.

는 기사를 삭제하지만, 살아 속한 모든 카테고리를 유지 :

using (var dbContext = new MyDbContext(...)) 
{ 
    Article articleToRemove = ... 
    dbContext.Articles.Remove(articleToRemove); 
    dbContext.SaveChanges(); 
} 

엔티티 프레임 워크는 자동으로 적절한 조인을 수행하고, 모든 카테고리에서 articleToRemove을 제거합니다. 그러나 카테고리는 제거되지 않습니다.

사실 내부적으로 Categories 테이블은 전혀 변경되지 않습니다. Article.Id가있는 모든 레코드는 접합 테이블에서 제거됩니다.

+0

위대한 설명, 고마워요. – Martin