2013-10-11 2 views
28

"자식"행을 삭제하려고하면 항상 예외가 발생합니다.EF6.0 "하나 이상의 외래 키 속성이 nullable이 아니기 때문에 관계를 변경할 수 없습니다."

using (var context = new CompanyContext()) 
{ 
    ItemType itemType = context.ItemTypes.FirstOrDefault(i => i.Name == "ServerType"); 
    ItemTypeItem itemTypeItem = itemType.Items.FirstOrDefault(i => i.Name == "DatabaseServer"); 
    itemType.Items.Remove(itemTypeItem); 
    context.SaveChanges(); <=== exception! 
} 

다음과 같은 예외가 SaveChanges() 방법에서 발생한다 : 여기 snipset이다. 하나 이상의 외부 키 속성 이상의 비 널 때문에

"는 관계가 변경 될 수있다. 변화가 관계로 제조되는 경우, 관련 외부 키 속성은 널 (null) 값으로 설정된다. 외래 키가 null 값을 지원하지 않으면 새 관계를 정의해야하며 외래 키 속성에 다른 null이 아닌 값을 할당해야합니다. 그렇지 않으면 관련이없는 개체를 삭제해야합니다. "

엔티티 구성

public class ItemTypeConfiguration : NamedEntityConfiguration<ItemType> 
    { 
    public ConfigurationColumn ParentIDColumn; 
    public ConfigurationColumn ValidationPatternColumn; 
    public ItemTypeConfiguration() : base() 
    { 
     ParentIDColumn = new ConfigurationColumn() { Name = "ParentID", Ordinal = base.LastOrdinalPosition + 1 }; 
     ValidationPatternColumn = new ConfigurationColumn() { Name = "ValidationPattern", Length = 1024, Ordinal=base.LastOrdinalPosition + 2}; 
     this.Property(t => t.ParentID) 
     .HasColumnName(ParentIDColumn.Name) 
     .HasColumnOrder(ParentIDColumn.Ordinal); 
     this.HasOptional(t => t.Parent).WithMany().HasForeignKey(u => u.ParentID).WillCascadeOnDelete(false); 
     this.Property(t => t.ValidationPattern) 
     .HasColumnName(ValidationPatternColumn.Name) 
     .HasColumnOrder(ValidationPatternColumn.Ordinal) 
     .HasMaxLength(ValidationPatternColumn.Length); 
    } 
... 


    public class ItemTypeItemConfiguration : NamedEntityConfiguration<ItemTypeItem> 
    { 
    public ConfigurationColumn ItemTypeIDColumn; 
    public ItemTypeItemConfiguration() : base() 
    { 
     ItemTypeIDColumn = new ConfigurationColumn(){Name="ItemTypeID", IsRequired=true, Ordinal= base.LastOrdinalPosition+1}; 
     this.Property(t => t.ItemTypeID) 
     .HasColumnName(ItemTypeIDColumn.Name) 
     .HasColumnOrder(ItemTypeIDColumn.Ordinal); 
     this.HasRequired(t => t.ItemType).WithMany(t=>t.Items).HasForeignKey(u => u.ItemTypeID).WillCascadeOnDelete(true); 
    } 
... 

enter image description here

나는 블로그를 발견하지만 난 "DeleteObject 매크로"방법이 없습니다.

http://blog.clicdata.com/2013/07/04/the-operation-failed-the-relationship-could-not-be-changed-because-one-or-more-of-the-foreign-key-properties-is-non-nullable/

어떤 아이디어가? 고맙습니다.

+0

의 중복 가능성 [하나 또는 외래 키 속성의 이상이 아닌 Null을 허용하기 때문에 관계를 변경할 수 없습니다 (HTTP ://stackoverflow.com/questions/5538974/the-relationship-could-not-be-changed-one-or-or-of-the-foreign-key-pro) –

+0

링크가 다운되었습니다 –

답변

46

ItemTypeItem을 삭제해야합니다. ItemType (ItemTypeID)을 참조하는 Null을 허용하지 않는 외래 키가 있으므로 항목 목록에서 항목을 제거 할 수 없습니다.

의 주요 문맥이 작동 설정에서 당신이 개체를 제거하면 ItemTypeItem 엔티티 프레임 워크 6.0

context.Entry(itemTypeItem).State = EntityState.Deleted; 
+2

그 이유는 이상합니다. EntityState를하지 않고 항목을 추가 할 수 있습니다. 추가 ...하지만 그 사람, 고마워요! 이제는 동일한 작업을 수행하기 위해 저장소를 변경하는 방법을 찾아야합니다. 문맥에서 바로 테스트했습니다. EF는 배울 정도로 많은 블랙 박스입니다 !!! – Max

+1

나는 아래 답변으로 @Gerry를 읽었을 때만이 대답을 이해합니다. 핵심은 엔티티 부모가 아닌'context'에서 그것을 삭제하는 것입니다 ... –

+0

새로운 엔터티를 추가하는 동안 나는 여기 @Max에 동의합니다. 그냥 컬렉션에 추가 할 수 있고 DB 컨텍스트가이를 처리합니다. 상태를'Added'로 설정할 필요는 없습니다. 그러나 삭제를 위해서 컬렉션에서 삭제할 수는 없으며 컨텍스트에서 삭제하고 상태를 삭제 된 것으로 표시해야합니다 ... 혼란스러운 – LP13

40

을 추가, 삭제합니다.

context.Investments.Remove(entity); 
context.SaveChanges(); 

이 다음과 같이 부모/소유자로부터 엔티티를 제거하기 다릅니다 :

bankAccount.Investments.Remove(entity); 
context.SaveChanges(); 

이가 던질 것이다 예는 투자 법인을 제거하려면 다음을 수행 할 것 관계는 위에 나열된 예외를 변경할 수 없습니다. 희망이 도움이됩니다. EF는 내부적으로 자식 컬렉션의 필요한 삭제를 수행, 제 1 및 계단식 삭제가 활성화되어 사용하는 경우

context.Investments.Remove(entity); 

context.Entry(entity).State = EntityState.Deleted; 

: 엔티티 6.0

17

는 차이가있다. 두 번째 옵션을 사용할 때 EF는 필요한 삭제를 처리하지 않지만 이러한 하위 개체의 리 바인드/삭제를 처리 할 수있게합니다.

+2

내 하루를 저장했습니다. 올바른 계단식 삭제 구성이 있지만 동일한 예외가 발생합니다. 더 놀라운 사실은 백엔드로 SQL Server를 완벽하게 구현 한 녹색 단위 테스트에서 계단식 삭제가 시작된다는 것입니다.이 주석은 나를 생각하게 만들고 문제를 해결하는 데 도움이되었습니다. context.Set . 엔티티가 context.Entry (entity) .State = Deleted는 키를 제공하고 스텁 엔터티를 생성 할 때만 작동합니다. –

1

이 문제는 여전히 자식 테이블 데이터가있는 부모 테이블을 삭제하려고하기 때문에 발생합니다. 캐스케이드 삭제를 통해 문제를 해결합니다.

dbcontext 클래스의 Create 메소드에서 모델.이 간단한 코드뿐만 아니라 부모 관련 자식 테이블의 부모를 삭제 우리의 API 호출

var JobList = Context.Job      
      .Include(x => x.JobSportsMappings)          .ToList(); 
Context.Job.RemoveRange(JobList); 
Context.SaveChanges(); 

계단식 삭제 옵션에서 그 후

modelBuilder.Entity<Job>() 
       .HasMany<JobSportsMapping>(C => C.JobSportsMappings) 
       .WithRequired(C => C.Job) 
       .HasForeignKey(C => C.JobId).WillCascadeOnDelete(true); 
      modelBuilder.Entity<Sport>() 
       .HasMany<JobSportsMapping>(C => C.JobSportsMappings) 
        .WithRequired(C => C.Sport) 
        .HasForeignKey(C => C.SportId).WillCascadeOnDelete(true); 

. 이 간단한 방법으로 시도하십시오.

데이터베이스 감사 레코드의 목록을 삭제에 사용

제거 범위