2024. 4. 6. 15:30

FK(ForeingKey)를 설정하고 자식으로 대상을 추가하면 자식이 검색되지 않는 현상을 발견했습니다.

 

 

1. 증상 재연 

부모를 아래와 같이 만듭니다.

/// <summary>
/// FK키가 자동으로 증가되는 오류 재연용1
/// </summary>
public class AutoIncreases_Test1
{
    /// <summary>
    /// 고유키
    /// </summary>
    [Key]
    public long idAutoIncreases_Test1 { get; set; }

    /// <summary>
    /// 표시 데이터
    /// </summary>
    public string Name { get; set; } = string.Empty;


    /// <summary>
    /// 외래키에 연결된 리스트
    /// </summary>
    [ForeignKey("idAutoIncreases_Test1")]
    public ICollection<AutoIncreases_Test2> Test2 { get; set; } = new List<AutoIncreases_Test2>();

    /// <summary>
    /// 외래키에 연결된 리스트
    /// </summary>
    [ForeignKey("idAutoIncreases_Test1")]
    public ICollection<AutoIncreases_Test3> Test3 { get; set; } = new List<AutoIncreases_Test3>();
}

 

 

재연용 자식은 아래와 같습니다.

/// <summary>
/// FK키가 자동으로 증가되는 오류 재연용
/// </summary>
public class AutoIncreases_Test3
{
    /// <summary>
    /// 고유키
    /// </summary>
    [Key]
    public long idAutoIncreases_Test3 { get; set; }

    /// <summary>
    /// 표시 데이터
    /// </summary>
    public string Name { get; set; } = string.Empty;

    /// <summary>
    /// 연결된 외래키
    /// </summary>
    [ForeignKey("idAutoIncreases_Test1")]
    public long idAutoIncreases_Test1 { get; set; } = 0;
    /// <summary>
    /// 외래키에 연결된 대상
    /// </summary>
    public AutoIncreases_Test1 Test1 { get; set; } = new AutoIncreases_Test1();
}

 

 

이제 DB를 연결하고 부모를 한 개 추가한 후 해당 부모와 연결된 자식을 10개 추가해 봅시다.

 

그리고 나서 FK로 자식을 검색하면....

 

앵??? 자식을 10개 추가했는데 한 개 만나옵니다.

 

모든 자식을 검색해 봅시다.

 

앵???

FK가 하나씩 증가했습니다?

 

 

2. 해결 방법 

이것은 외래키 개체 연결용으로 만든  'AutoIncreases_Test3.Test1'가 새로 생성되면서 발생하는 문제입니다.

'new AutoIncreases_Test1()'를 하여 새 개체를 할당하므로 지 혼자 원래 연결해야 할 대상이 아니 새로운 대상이라고 판단하고 저렇게 동작하는 것이죠.

 

그러니 외래키 연결 대상은 'new'로 할당하면 안 됩니다.

 

정상적인 자식 모델을 만들어 봅시다.

/// <summary>
/// FK키가 자동으로 증가되는 오류가 없음
/// </summary>
public class AutoIncreases_Test2
{
    /// <summary>
    /// 고유키
    /// </summary>
    [Key]
    public long idAutoIncreases_Test2 { get; set; }

    /// <summary>
    /// 표시 데이터
    /// </summary>
    public string Name { get; set; } = string.Empty;


    /// <summary>
    /// 연결된 외래키
    /// </summary>
    [ForeignKey("idAutoIncreases_Test1")]
    public long idAutoIncreases_Test1 { get; set; } = 0;
    /// <summary>
    /// 외래키에 연결된 대상
    /// </summary>
    public AutoIncreases_Test1? Test1 { get; set; }
}

 

26번 줄 : 이전 자식과 달리 'new'로 새 개체를 할당하지 않고 있습니다.

대신 '생성자를 종료할 때 null을 허용하지 않는 속성 'Test1'에 null이 아닌 값을 포함해야 합니다. 속성을(를) null 허용으로 선언해 보세요.' 경고가 발생하므로 널(null) 허용으로 선언해 줍니다.

 

 

이제 실행해 봅시다.

 

 

정상적으로 FK가 생성되어 연결되는 것을 볼 수 있습니다.

 

문제가 있다면 부모와 자식이 1:1로 매칭되는 경우 널(null) 일리가 없지만 널(null) 검사를 해야 한다는 점이죠.

 

 

마무리 

테스트 프로젝트 :

github - dang-gun/EntityFrameworkSample/ForeignKeyTest 에서

1. FK Auto Increases - 부모 기준 검색

2. FK Auto Increases - 자식 기준 검색

 

참고 : stackoverflow - Entity Framework Core 6 is auto incrementing non-key columns에서 'Serge'님 답변

 

결국 좀 불편하더라도 널(null)을 허용하는 게 멀쩡하게 돌아갑니다.

이런 실수는 해봐야 기억에 남는 실수긴 한데 말이죠 ㅎㅎㅎㅎ