본문 바로가기

컴퓨터

엔터티 유형 EF 마이그레이션에는 여러 탐색이 있습니다.

현재 다음과 같은 스키마 모델에서 EF 마이그레이션 스크립트를 만들고 있습니다.

public class Schema : RootId
{
public int Version { get; set; }

[ForeignKey("entity_id")]
public virtual ICollection Entities { get; set; } = null!;

[ForeignKey("entity_id")]
public virtual ICollection Relations { get; set; } = null!;
}
여기서 두 관계 모두 동일한 객체 유형을 사용하고 마이그레이션을 수행하면 오류가 발생합니다.

There are multiple navigations in entity type 'Schema' which are pointing to same set of properties using a [ForeignKey] attribute: 'entity_id'
둘 다에 대한 외래 키가 entity_id이기 때문에 사실입니다. 그러나 이것은 이전에 작동했지만 그 당시에는 유형이였으며 ICollection이는 Entity코드 중복을 도입하기 때문에 의미가없는 의 완전한 사본이었습니다 .

어떻게 변환합니까 Relations에 ICollectionforeing_key ENTITY_ID을 사용할 수 있도록 계속하고 - 그것은 혼란 유형의 메이크업을 변경하는 방법이하지 않는 무엇인가?

최신 정보:

좋아, 이렇게 해봤 어

public class Schema : RootId
{
public int Version { get; set; }

[ForeignKey("entity_id")]
public virtual ICollection Entities { get; set; } = null!;

[ForeignKey("entity_id")]
public virtual ICollection Relations { get; set; } = null!;
}

public class Entity : BaseEntity
{
}

public class Relation : BaseEntity
{
}

public class BaseEntity : RootId
{
}
그러나 이것은 테이블을 삽입하거나 업데이트 할 때마다 외래 키 위반을 유발합니까? ...

"Key (attribute_entity_id)=(4) is not present in table "relation"."
씨#
엔티티 프레임 워크
엔티티 프레임 워크 코어
ef 코드 우선
공유 이 질문을 개선 따르다
생성 21 nov.
생성 18 nov.

카프카
811은색 배지 1 개12청동 휘장 12 개
2
외래 키가 컬렉션 탐색 속성을 포함하는 엔터티가 아니라 관계의 다른 쪽 ( Entity이 경우)에 있다는 것을 알고 있습니다 . 맞습니까? 그렇다면 하나의 속성이 엔티티가 속한 두 컬렉션 중 어느 것을 알 수 있다고 어떻게 기대합니까? 이전 디자인이 무엇인지,이 모델로 무엇을 달성하려고하는지 확실하지 않은 경우, 지금의 방식은 단순히 작동하지 않고 만들 수 없다는 것뿐입니다. 클래스 Schema에서 가리키는 2 개의 FK 속성이있는 경우를 제외하고는 Entity어떤 btw가 게시물에 포함되어야합니다. – Ivan Stoev 11 월 20 일 15:17
다형성 연관을 찾아 보면 이것이 Stack Overflow에서 지속적으로 반복되는 주제임을 알 수 있습니다. – Gert Arnold 11 월 21 일 10:14
의견을 추가하다
3 개의 답변

2

모델을 약간 변경하여 수정할 수 있습니다. Entities 및 Relations 컬렉션 모두에 대해 서로 다른 외래 키를 정의하기 만하면됩니다.

public class Schema
{
public int Id { get; set; }

public int Version { get; set; }

public virtual ICollection<Entity> Entities { get; set; } = null!;

public virtual ICollection<Entity> Relations { get; set; } = null!;

}

public class Entity
{
public int Id { get; set; }

public int SchemaAsEntityId { get; set; }
[ForeignKey("SchemaAsEntityId")]
public Schema SchemaAsEntity { get; set; }

public int SchemaAsRelationId { get; set; }
[ForeignKey("SchemaAsRelationId")]
public Schema SchemaAsRelation { get; set; }

}
또한 엔티티가 다른 모델과 동시에 여러 외래 키를 만들기 때문에 OnModelCreating에 다음 구성이 필요합니다.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);

modelBuilder.Entity<Schema>().HasMany(x => x.Entities).WithOne(x => x.SchemaAsEntity)
            .HasForeignKey(x => x.SchemaAsEntityId).IsRequired().OnDelete(DeleteBehavior.ClientSetNull);

modelBuilder.Entity<Schema>().HasMany(x => x.Relations).WithOne(x => x.SchemaAsRelation)
            .HasForeignKey(x => x.SchemaAsRelationId).IsRequired().OnDelete(DeleteBehavior.ClientSetNull);

}

공유 이 답변을 개선 따르다
어제 답변

사이드 아 미니
8982골드 배지 2 개6은색 배지 6 개18청동 휘장 18 개
의견을 추가하다

1

실제 데이터 모델이 작동하지 않는 것 같습니다. 다음을 상상해보십시오. 연결된 "Entity"개체를 포함하여 "Schema"테이블에서 데이터를 가져 오는 경우 EF Core는 "Entity"가 Entites 컬렉션에 있어야하는지 여부를 알 수 없습니다. 또는 관계 컬렉션에서.

"이"가 실제로 이전에 작동했다고 말했지만 :

이것은 이전에 작동했지만 그 당시에는 유형이 ICollection이었는데, 이는 Entity의 완전한 사본이었는데, 이것은 코드 중복을 도입하기 때문에 의미가 없습니다.

이 경우 "관계"개체 / 테이블을 유지합니다. 코드 중복을 방지하려면 상속을 사용하면됩니다.

class Relation : Entity {}

이것은 관계 테이블과 엔티티 테이블을 의미하지만 코드 중복은 없습니다.

... 나는 당신의 편집을 보았고, 나는 당신의 새로운 문제를 더 잘 이해하기 위해 코멘트를 할 수 없습니다.

공유 이 답변을 개선 따르다
생성 21 nov.
생성 21 nov.

데이비드-아오
11삼브론즈 배지 3 개
의견을 추가하다

1

여기서 기본적으로 달성하려는 것은 엔티티 클래스에 동일한 외래 키 2 개가 있어야한다고 말하는 것입니다. 이와 [ForeignKey]같이 컬렉션 에 속성을 추가하면 대상 테이블에 외래 키를 만들려고 함을 의미합니다.이 경우 테이블은 엔티티이고 엔티티는 동일한 이름을 가진 두 개의 외래 키를 가질 수 없습니다. 두 개의 다른 관계에 대해 동일한 외래 키를 원하는 이유는 무엇입니까? 내가 직접 도움을 줄 충분한 컨텍스트가 없지만 각 관계에 대해 2 개의 다른 외래 키를 만들 수 있습니다. 예를 들면 :

public class Schema : RootId
{
public int Version { get; set; }

[ForeignKey("schema_Id")]
public virtual ICollection Entities { get; set; } = null!;

[ForeignKey("schema_Id")]
public virtual ICollection Relations { get; set; } = null!;
}
나는 이것이 당신의 문제를 해결할 것이라고 생각합니다