[asp.net-mvc-3] MVC3에서 Code First Entity Framework (4.1)를 사용하여 외래 키 관계를 어떻게 선언해야합니까?

나는 많은 운없이 코드 우선 EF 4.1을 사용하여 외래 키 관계 및 기타 제약 조건을 선언하는 방법에 대한 리소스를 찾고 있습니다. 기본적으로 코드로 데이터 모델을 만들고 MVC3를 사용하여 해당 모델을 쿼리합니다. 모든 것이 훌륭한 MVC를 통해 작동하지만 (Microsoft에 대한 쿠도스!) 데이터 모델 제약이 필요하기 때문에 작동하지 않기를 원합니다.

예를 들어, 외부 개체 (테이블) 인 속성이 많은 Order 개체가 있습니다. 지금은 주문을 만들 수 있지만 외래 키 또는 외부 개체를 추가 할 수 없습니다. MVC3는 이것을 문제없이 설정합니다.

저장하기 전에 컨트롤러 클래스에 직접 개체를 추가 할 수 있다는 것을 알고 있지만 제약 조건 관계가 충족되지 않으면 DbContext.SaveChanges () 호출이 실패하고 싶습니다.

새로운 정보

따라서 특히 고객 개체를 지정하지 않고 Order 개체를 저장하려고 할 때 예외가 발생하고 싶습니다. 대부분의 Code First EF 문서에 설명 된대로 개체를 구성하는 경우에는 이것이 동작이 아닌 것 같습니다.

최신 코드 :

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

    [ForeignKey( "Parent" )]
    public Patient Patient { get; set; }

    [ForeignKey("CertificationPeriod")]
    public CertificationPeriod CertificationPeriod { get; set; }

    [ForeignKey("Agency")]
    public Agency Agency { get; set; }

    [ForeignKey("Diagnosis")]
    public Diagnosis PrimaryDiagnosis { get; set; }

    [ForeignKey("OrderApprovalStatus")]
    public OrderApprovalStatus ApprovalStatus { get; set; }

    [ForeignKey("User")]
    public User User { get; set; }

    [ForeignKey("User")]
    public User Submitter { get; set; }

    public DateTime ApprovalDate { get; set; }
    public DateTime SubmittedDate { get; set; }
    public Boolean IsDeprecated { get; set; }
}

이것은 환자에 대한 VS 생성보기에 액세스 할 때 발생하는 오류입니다.

에러 메시지

‘PhysicianPortal.Models.Order’유형의 ‘Patient’속성에 대한 ForeignKeyAttribute가 유효하지 않습니다. 종속 유형 ‘PhysicianPortal.Models.Order’에서 외래 키 이름 ‘Parent’를 찾을 수 없습니다. 이름 값은 쉼표로 구분 된 외래 키 속성 이름 목록이어야합니다.

문안 인사,

귀도



답변

당신이있는 경우 Order클래스, 속성을 추가 참조 모델의 또 다른 클래스는, 예를 들어 것을 CustomerEF는 관계가 거기에있다 알려 충분해야한다 :

public class Order
{
    public int ID { get; set; }

    // Some other properties

    // Foreign key to customer
    public virtual Customer Customer { get; set; }
}

FK관계 는 항상 명시 적으로 설정할 수 있습니다 .

public class Order
{
    public int ID { get; set; }

    // Some other properties

    // Foreign key to customer
    [ForeignKey("Customer")]
    public string CustomerID { get; set; }
    public virtual Customer Customer { get; set; }
}

ForeignKeyAttribute생성자는 매개 변수로 문자열을 사용합니다 : 당신이 외래 키 특성에 배치하는 경우는 관련 탐색 속성의 이름을 나타냅니다. 탐색 속성에 배치하면 연결된 외래 키의 이름을 나타냅니다.

이것이 의미하는 바는 속성 ForeignKeyAttribute에 를 배치 할 Customer경우 속성이 CustomerID생성자에서 가져 옵니다.

public string CustomerID { get; set; }
[ForeignKey("CustomerID")]
public virtual Customer Customer { get; set; }

최신 코드를 기반으로 편집
다음 줄 때문에 오류가 발생합니다.

[ForeignKey("Parent")]
public Patient Patient { get; set; }

EF는 Parent외래 키 시행자로 사용하기 위해 호출 된 속성을 찾습니다 . 다음 두 가지 작업을 수행 할 수 있습니다.

1) 제거하고 필요에 따라 관계를 표시하기 위해로 ForeignKeyAttribute교체하십시오 RequiredAttribute.

[Required]
public virtual Patient Patient { get; set; }

로 속성을 장식하는 RequiredAttribute것도 좋은 부작용이 ON DELETE CASCADE있습니다. 데이터베이스의 관계는 .

또한 virtualLazy Loading을 사용 하도록 속성 을 만드는 것이 좋습니다 .

2) Parent외래 키로 사용할 속성을 만듭니다 . 이 경우 예를 들어 호출하는 것이 더 합리적 일 것입니다 ParentID(이름도 변경해야합니다 ForeignKeyAttribute).

public int ParentID { get; set; }

이 경우 내 경험 상으로는 다른 방법으로 사용하는 것이 더 좋습니다.

[ForeignKey("Patient")]
public int ParentID { get; set; }

public virtual Patient Patient { get; set; }


답변

다음과 같이 외래 키를 정의 할 수 있습니다.

public class Parent
{
   public int Id { get; set; }
   public virtual ICollection<Child> Childs { get; set; }
}

public class Child
{
   public int Id { get; set; }
   // This will be recognized as FK by NavigationPropertyNameForeignKeyDiscoveryConvention
   public int ParentId { get; set; }
   public virtual Parent Parent { get; set; }
}

이제 ParentId는 외래 ​​키 속성이며 자식과 기존 부모 사이에 필요한 관계를 정의합니다. 기존 부모없이 자식을 저장하면 예외가 발생합니다.

FK 속성 이름이 탐색 속성 이름과 상위 PK 이름으로 구성되지 않은 경우 ForeignKeyAttribute 데이터 주석 또는 Fluent API를 사용하여 관계를 매핑해야합니다.

데이터 주석 :

// The name of related navigation property
[ForeignKey("Parent")]
public int ParentId { get; set; }

Fluent API :

modelBuilder.Entity<Child>()
            .HasRequired(c => c.Parent)
            .WithMany(p => p.Childs)
            .HasForeignKey(c => c.ParentId);

다른 유형의 제약 조건은 데이터 주석 및 모델 유효성 검사를 통해 적용 할 수 있습니다 .

편집하다:

을 설정하지 않으면 예외가 발생합니다 ParentId. 필수 속성입니다 (null 허용 아님). 설정하지 않으면 아마도 데이터베이스에 기본값을 보내려고 할 것입니다. 기본값은 0이므로 Id = 0 인 고객이없는 경우 예외가 발생합니다.


답변