엔터티 프레임 워크에서 1 : 1 관계에서 연결의 주요 끝은 무엇을 의미합니까?


269
public class Foo
{
    public string FooId{get;set;}
    public Boo Boo{get;set;}
}


public class Boo
{
    public string BooId{get;set;}
    public Foo Foo{get;set;}
}

오류가 발생했을 때 Entity Framework 에서이 작업을 수행하려고했습니다.

'ConsoleApplication5.Boo'및 'ConsoleApplication5.Foo'유형 간 연관의 주요 끝을 판별 할 수 없습니다. 이 연결의 주요한 끝은 관계 유창 API 또는 데이터 주석을 사용하여 명시 적으로 구성해야합니다.

이 오류에 대한 해결책으로 StackOverflow에서 질문을 보았지만 "주요 목적"이라는 용어의 의미를 이해하고 싶습니다.


용어에 대한 설명은 docs.microsoft.com/en-us/ef/core/modeling/relationships 를 참조하십시오.
DeepSpace101

답변:


378

일대일 관계에서 한쪽 끝은 기본이고 다른 쪽 끝은 종속적이어야합니다. 기본 끝은 먼저 삽입되고 종속 끝없이 존재할 수있는 끝입니다. 종속 엔드는 프린시 펄에 대한 외부 키가 있으므로 프린시 펄 뒤에 삽입해야하는 엔드 포인트입니다.

엔티티 프레임 워크의 경우 종속적 인 FK도 PK이어야하므로 귀하의 경우 다음을 사용해야합니다.

public class Boo
{
    [Key, ForeignKey("Foo")]
    public string BooId{get;set;}
    public Foo Foo{get;set;}
}

또는 유창한 매핑

modelBuilder.Entity<Foo>()
            .HasOptional(f => f.Boo)
            .WithRequired(s => s.Foo);

6
@Ladislav, 둘 다 서로에 대한 선택적 참조가있는 두 개의 독립 테이블을 만들어야합니다 (일대일). 둘 다 자신의 PK를 갖기를 원합니다. 어떻게 가능합니까? 별도의 질문을 게시했습니다 .
Shimmy Weitzhandler

10
당신은 이것에 대한 답을 찾는 데 얼마나 많은 시간이 걸 렸는지 알지 못합니다-ms documentation은 POOOOOOP ty입니다.
gangelo

1
System.ComponentModel.DataAnnotations.Schema를 사용하여 추가해야 할 수도 있습니다. VS2012에서 ForeignKey를 얻는 방법
stuartdotnet

2
그게 그것이 Foo교장 이라는 것을 의미합니까 ?
bflemi3

8
@ bflemi3 당신이 올바른 Boo것은 의존적이며,를 필요로 Foo하며 외래 키를 얻습니다. Foo주체이며 Boo. 없이 존재할 수 있습니다 .
콜린

182

[Required]데이터 주석 속성을 사용하여 이를 해결할 수도 있습니다 .

public class Foo
{
    public string FooId { get; set; }

    public Boo Boo { get; set; }
}

public class Boo
{
    public string BooId { get; set; }

    [Required]
    public Foo Foo {get; set; }
}

Foo에 필요합니다 Boo.


이것은 다음 코드에 대해 정확했습니다. 여기서 두 개 사이의지도를 별도의 엔터티 클래스로 공개하고 싶었습니다. {public int Id {get; 세트; }} 공개 클래스 사용자 {public int Id {get; 세트; }} 공개 클래스 UserGroup {[Key] 공개 int Id {get; 세트; } [필수] 공개 가상 조직 조직 {get; 세트; } [필수] 공개 가상 사용자 사용자 {get; 세트; }}
AndyM

Oracle을 사용하고 있으며 유창한 API 중 어느 것도 나를 위해 일하지 않았습니다. 고마워 친구. 너무 간단합니다.
CameronP

11
이 솔루션을 사용할 때는 Boo먼저 Foo속성 의 지연로드를 트리거하지 않는 한 데이터베이스에서 방금 검색 한 업데이트를 시도 할 때 유효성 검사 예외가 발생합니다 . entityframework.codeplex.com/SourceControl/network/forks/…
NathanAldenSr

2
Boo Boo그때 가상 해서는 안 됩니까?
Simon_Weaver

1
@NathanAldenSr 링크가 잘못되었습니다. 어떻게 변경합니까?
CamHart

9

이것은 일대일 관계를 구성하기 위해 유창한 API를 사용하는 것에 대한 @Ladislav Mrnka의 답변과 관련이 있습니다.

FK of dependent must be it's PK가능하지 않은 상황이 있었습니다.

예를 들어 Foo이미와 일대 다 관계가 Bar있습니다.

public class Foo {
   public Guid FooId;
   public virtual ICollection<> Bars; 
}
public class Bar {
   //PK
   public Guid BarId;
   //FK to Foo
   public Guid FooId;
   public virtual Foo Foo;
}

이제 Foo와 Bar간에 일대일 관계를 추가해야했습니다.

public class Foo {
   public Guid FooId;
   public Guid PrimaryBarId;// needs to be removed(from entity),as we specify it in fluent api
   public virtual Bar PrimaryBar;
   public virtual ICollection<> Bars;
}
public class Bar {
   public Guid BarId;
   public Guid FooId;
   public virtual Foo PrimaryBarOfFoo;
   public virtual Foo Foo;
}

유창한 API를 사용하여 일대일 관계를 지정하는 방법은 다음과 같습니다.

modelBuilder.Entity<Bar>()
            .HasOptional(p => p.PrimaryBarOfFoo)
            .WithOptionalPrincipal(o => o.PrimaryBar)
            .Map(x => x.MapKey("PrimaryBarId"));

PrimaryBarId유창한 API를 통해 추가하는 동안 추가 를 제거해야합니다.

또한 메소드 이름 [WithOptionalPrincipal()][1]은 역설적입니다. 이 경우 교장은 바입니다. msdn에 OptionalDependent () 설명을 사용하면 더 명확 해집니다.


2
당신이 실제로 경우 원하는PrimaryBarId 속성을? 이것은 나에게 우스운 일입니다. 속성을 추가하고 외래 키라고 말하면 오류가 발생합니다. 그러나 부동산이 없으면 EF가 어쨌든 만들 것입니다. 차이점이 뭐야?
Chris Pratt

1
@ChrisPratt 이것은 합리적으로 들리지 않을 수 있습니다. 나는 흔적과 오류 후에이 솔루션에 도달했습니다. 엔터티에 PrimayBarId속성이 있을 때 일대일 매핑을 구성 할 수 없었습니다 Foo. 아마도 당신이 시도한 것과 같은 해결책 일 것입니다. 아마도 EF의 한계?
Sudarshan_SMD

3
그래 나는 지금까지 EF가 독특한 인덱스를 구현하지 않았다는 것을 알게되었습니다. 결과적으로 일대일을 매핑 할 수있는 유일한 방법은 기본 키의 특성이 고유하기 때문에 기본 엔드의 기본 키를 종속 엔드의 기본 키로 사용하는 것입니다. 다시 말해, 그들은 반으로 구현했고 테이블을 비표준 방식으로 디자인해야한다는 지시를 내 렸습니다.
Chris Pratt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.