Entity Framework 6 : 코드 첫 번째 계단식 삭제

c# entity-framework entity-framework-6 sql

문제

그래서 여기에 몇 가지 비슷한 질문이 있지만, 단순화 된 시나리오에서 정확히 내가 빠진 것이 무엇인지를 결정하는 데 문제가 있습니다.

나 자신을 똑똑하게 명명 한 다음 표가 있다고 가정 해 봅시다.

'JohnsParentTable' (Id, Description) 
'JohnsChildTable' (Id, JohnsParentTableId, Description)

결과 클래스는 그렇게 보입니다.

public class JohnsParentTable
{
    public int Id { get; set; }
    public string Description { get; set; }
    public virtual ICollection<JohnsChildTable> JohnsChildTable { get; set; }

    public JohnsParentTable()
    {
        JohnsChildTable = new List<JohnsChildTable>();
    }
}

internal class JohnsParentTableConfiguration : EntityTypeConfiguration<JohnsParentTable>
{
    public JohnsParentTableConfiguration()
    {
        ToTable("dbo.JohnsParentTable");
        HasKey(x => x.Id);
        Property(x => x.Id).HasColumnName("Id").IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        Property(x => x.Description).HasColumnName("Description").IsRequired().HasMaxLength(50);
    }
}

public class JohnsChildTable
{
    public int Id { get; set; }
    public string Description { get; set; }
    public int JohnsParentTableId { get; set; }
    public JohnsParentTable JohnsParentTable { get; set; }
}

internal class JohnsChildTableConfiguration : EntityTypeConfiguration<JohnsChildTable>
{
    public JohnsChildTableConfiguration()
    {
        ToTable("dbo.JohnsChildTable");
        HasKey(x => x.Id);
        Property(x => x.Id).HasColumnName("Id").IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        Property(x => x.Description).HasColumnName("Description").IsRequired().HasMaxLength(50);
        HasRequired(a => a.JohnsParentTable).WithMany(c => c.JohnsChildTable).HasForeignKey(a => a.JohnsParentTableId);
    }
}

데이터베이스에서이 부모에 연결된 자식 테이블의 두 행과 함께 1의 ID를 가진 부모 테이블에 행이 있습니다. 내가 이렇게하면 :

var parent = db.JohnsParentTable.FirstOrDefault(a => a.Id == 1)

개체가 올바르게 채워집니다. 그러나이 행을 삭제하려고하면 :

var parent = new Data.Models.JohnsParentTable() { Id = 1 };
db.JohnsParentTable.Attach(parent);
db.JohnsParentTable.Remove(parent);

db.SaveChanges();

엔터티 프레임 워크는 다음을 실행하려고 시도합니다.

DELETE [dbo].[JohnsParentTable]
WHERE ([Id] = @0)
-- @0: '1' (Type = Int32)
-- Executing at 1/23/2014 10:34:01 AM -06:00
-- Failed in 103 ms with error: The DELETE statement conflicted with the REFERENCE constraint "FK_JohnsChildTable_JohnsParentTable". The conflict occurred in database "mydatabase", table "dbo.JohnsChildTable", column 'JohnsParentTableId'.
The statement has been terminated.

그런 다음 내 질문은 부모 프레임을 삭제하기 전에 'JohnsChildTable'행을 삭제해야한다는 것을 Entity Framework에서 확실히 알 수 있도록 정확히 무엇이 누락 되었습니까?

수락 된 답변

Entity Framework에서 자식을 삭제할지 또는 데이터베이스에서 처리할지 여부에 따라 다릅니다.

EF가 모든 자식에 대해 delete 문을 생성하고 부모를 삭제하기 전에이를 실행하려면 모든 자식을 먼저 메모리에로드해야합니다.

따라서 단순히 채워진 키로 "더미"엔티티를 만들고 그 자식을 삭제할 수는 없습니다.

이를 위해서는 데이터베이스에서 삭제 작업을 처리하도록해야합니다.

그러나 자식 테이블의 외래 키는 계단식 삭제를 사용하도록 설정해야합니다. 그렇다면 Entity Framework는 부모에 대한 delete 문을 만들고 데이터베이스는 자식을 삭제하는 것을 알고 있습니다.

Entity Framework는 사용자의 경우와 같이 관계가 필요할 경우 기본적으로 활성화 된 계단식 삭제를 사용하여 외래 키를 만듭니다. 외래 키는 null 일 수 없습니다.

데이터베이스를 직접 작성한 경우이를 사용 가능하게해야합니다.


인기 답변

OnModelCreating 메서드를 재정의하고이 코드를 추가하는 것이 더 좋습니다.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
   modelBuilder.Entity<JohnsChildTable>()
               .HasRequired(t=>t.JohnsParentTable)
               .WithMany(t=>t.JohnsChildTables)
               .HasForeignKey(d=>d.JohnsParentTableId)
               .WillCascadeOnDelete(true);

            base.OnModelCreating(modelBuilder);
}

나는 사실로 설정했습니다. WillCascadeOnDelete (true)



Related

아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.