2013-01-23 4 views
0

일부 외래 키가 내 계약 테이블에 이중으로 생성됩니다. (기사 및 고객). 그리고 회사는 괜찮습니다!외래 키 데이터베이스에 중복 됨

내 모델 :이 오류가있다 아마 내 OnModelCreating입니다

public class Contract { 
    [Key] 
    public int ContractID { get; set; } 
    public double PricePerUnit { get; set; } 
    public int Unit { get; set; } 
    public int Currency { get; set; } 

    [Required] 
    public int ClientID { get; set; } 
    public virtual Client Client { get; set; } 

    [Required] 
    public int CompanyID { get; set; } 
    public virtual Company Company { get; set; } 

    [Required] 
    public int ArticleID { get; set; } 
    public virtual Article Article { get; set; } 

} 

public class Client { 
    [Key] 
    public int ClientID { get; set; } 
    public string Number { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string ZipCode { get; set; } 
    public string City { get; set; } 
    public string AddressLine1 { get; set; } 
    public string AddressLine2 { get; set; } 
    public string Memo { get; set; } 
    public bool isMerchant { get; set; } 

    public string Name 
    { 
     get 
     { 
      return string.Format("{0} {1}", FirstName, LastName); 
     } 
    } 

    //[Required] 
    public int? MerchantReferenceID { get; set; } 
    public virtual Client MerchantReference { get; set; } 
    [Required] 
    public int CompanyID { get; set; } 
    public virtual Company Company { get; set; } 
    public virtual ICollection<Contract> Contracts { get; set; } 
    public virtual ICollection<Order> Orders { get; set; } 
} 

public class Company 
{ 
    [Key] 
    public int CompanyID { get; set; } 
    public string Name { get; set; } 
    public int DeviceIncomingWeight { get; set; } 
    public string ZipCode { get; set; } 
    public string AddressLine1 { get; set; } 
    public string AddressLine2 { get; set; } 
    public string City { get; set; } 
    public bool Admin { get; set; } 
    public int UnitForMeasurements { get; set; } 
    public int UnitForDisplayOnDocuments { get; set; } 

    public virtual ICollection<User> Users { get; set; } 
    public virtual ICollection<Category> Categories { get; set; } 
    public virtual ICollection<Article> Articles { get; set; } 
    public virtual ICollection<Client> Clients { get; set; } 
    public virtual ICollection<Location> Locations { get; set; } 
    public virtual ICollection<Contract> Contracts { get; set; } 
    public virtual ICollection<IncomingMeasurement> IncomingMeasurements { get; set; } 
    public virtual ICollection<Measurement> Measurements { get; set; } 
    public virtual ICollection<Order> Orders { get; set; } 
} 

public class Article { 
    [Key] 
    public int ArticleID { get; set; } 
    [Required] 
    public string Code { get; set; } 
    public string Name { get; set; } 
    public bool TrackStock { get; set; } 
    public int CurrentStock { get; set; } 
    public double? Price { get; set; } 

    [Required] 
    public int CompanyID { get; set; } 
    public virtual Company Company { get; set; } 
    [Required] 
    public int CategoryID { get; set; } 
    public virtual Category Category { get; set; } 

    public virtual ICollection<Contract> Contracts { get; set; } 
    public virtual ICollection<Order> Orders { get; set; } 
} 

:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     // modelBuilder.Entity<Contract>().HasRequired(bm => bm.Company).WithMany().WillCascadeOnDelete(false); 
     modelBuilder.Entity<Contract>().HasRequired(bm => bm.Article).WithMany().WillCascadeOnDelete(false); 
     modelBuilder.Entity<Contract>().HasRequired(bm => bm.Client).WithMany().WillCascadeOnDelete(false); 
     modelBuilder.Entity<Article>().HasRequired(bm => bm.Company).WithMany().WillCascadeOnDelete(false); 
     modelBuilder.Entity<Measurement>().HasRequired(bm => bm.Company).WithMany().WillCascadeOnDelete(false); 
     modelBuilder.Entity<Order>().HasRequired(bm => bm.Client).WithMany().WillCascadeOnDelete(false); 
     modelBuilder.Entity<Order>().HasRequired(bm => bm.Article).WithMany().WillCascadeOnDelete(false); 
     modelBuilder.Entity<IncomingMeasurement>().HasRequired(bm => bm.client).WithMany().WillCascadeOnDelete(false); 
     modelBuilder.Entity<Client>().HasOptional(c => c.MerchantReference).WithMany().HasForeignKey(c => c.MerchantReferenceID); 

     //Required fields 


     base.OnModelCreating(modelBuilder); 
    } 

을 그리고 뭔가 이상한 일어나는 내 데시벨 (내 SQL 서버)에있다, 즉이다 내 테이블 스키마를 만듭니다.

CREATE TABLE [dbo].[Contracts](
[ContractID] [int] IDENTITY(1,1) NOT NULL, 
[PricePerUnit] [float] NOT NULL, 
[Unit] [int] NOT NULL, 
[Currency] [int] NOT NULL, 
[ClientID] [int] NOT NULL, 
[CompanyID] [int] NOT NULL, 
[ArticleID] [int] NOT NULL, 
[Client_ClientID] [int] NOT NULL, 
[Article_ArticleID] [int] NOT NULL, 
[Client_ClientID1] [int] NULL, 
[Article_ArticleID1] [int] NULL, 

당신이 그것을 발견하면 [Client_ClientID] 중복이 있습니다 :

이들은

내 필드입니다 [Client_ClientID1]도 [Article_ArticleID] [Article_ArticleID1]입니다. 하지만 회사는 그렇지 않습니다.

이 문제를 해결하는 방법에 대한 의견이 있으십니까?

답변

1

이것은 엔터티 클래스에 중복 (외래 키) 열을 포함하기 때문에 발생합니다. 예를 들어 Contract 클래스의 카테고리를 확인하십시오.

public class Contract 
{ 
    public Int32 CategoryID { get; set; } 

    public virtual Category Category { get; set; } 
} 

는 수동 특성 때문에 열 CategoryID를 지정한 다음 엔티티 프레임 워크는 부동산 Category에 의해 참조 Category에 대한 외부 키를 누른 상태에서 다른 열을 생성합니다.

따라서 참조 된 카테고리의 ID가 필요한 경우 CategoryID 속성을 삭제하고 contract.Category.CategoryID을 대신 사용하십시오.

UPDATE

는 내가 아마 자유로운 외부 키를 구성 섹션 에서 답을 발견 외래 키 프로퍼티하지만 제프 Siever의 대답에 코멘트에 링크 된 기사보고를 포함하는 제안을 인식하지 않았다 이름은입니다.

엔터티 프레임 워크

는 대문자 DNavigationPropertyNameID를 사용하는 동안 NavigationPropertyNameId 또는 NavigationPropertyName_Id 중 하나 인 탐색 속성의 이름과 외래 키 속성과 기본 규칙과 일치하는 규칙을 사용합니다.

몇 가지 옵션이 있습니다. 이름을 Id으로 바꾸거나, 규칙을 바꾸거나, 규칙을 재정의하십시오.

+0

다른 대답에 대한 내 의견보기 :) – NicoJuicy

+0

읽었습니다. 그리고이 문제를 발견하는 데 도움이되기를 바랍니다. 내 업데이트를 참조하십시오. –

+0

보기, 모델, 코드, ... ;-)를 변경하면 곧 업데이트됩니다. – NicoJuicy

0

모델에서 중복 된 정보를 제거하십시오. 참조 된 객체에 대한 ID는 필요하지 않으며 문제의 원인입니다.

public class Contract { 
    [Key] 
    public int ContractID { get; set; } 
    public double PricePerUnit { get; set; } 
    public int Unit { get; set; } 
    public int Currency { get; set; } 

    public virtual Client Client { get; set; } 

    public virtual Company Company { get; set; } 

    public virtual Article Article { get; set; } 
} 

id의 필수 속성 대신 하위 항목이 필요하도록 엔티티를 설정해야합니다.

+0

나는 그것을 과거에했지만 모든 공식 소식통은 외래 키로 int를 추가하는 것이 더 낫다고 말합니다. 예 : http://msdn.microsoft.com/en-us/data/hh134698.aspx.나는 또한 왜 그게 더 좋은지에 대한 표시 인 스카 폴딩의 개선점을 보았습니다. Article and Client에서 스캐 폴딩 문제가 있었는데 지금 바로이 문제가 있습니다. 저는 이것이 실제 해결책이라고 생각하지 않습니다. 과거에 해왔고 컨트롤러 + 뷰에서 스캐 폴딩을 일으키지 않습니다. 그래서 틀린 것이 입증 될 때까지 더 좋은 대답을 찾고 있습니다. – NicoJuicy

+0

추 신 : Scott Hanselmans의 예제 프로젝트조차도 (내가 어딘가에서 실수를하더라도) 내가하는 것처럼 그것을한다. http://nerddinner.codeplex.com/SourceControl/changeset/view/b1a032d1532b#mvc4/NerdDinner/Models/RSVP.cs – NicoJuicy

+0

OnModelCreating을 보았습니다. 속성을 두 번 지정해야하는 이유는 무엇입니까? 적절한 속성에 필수 속성이 있고 모델 생성에 HasRequired를 지정합니다. 나는 이것이 문제의 원인이라고 믿는다. 특히 회사는 괜찮 았고 계약 회사로부터의 HasRequired 라인은 주석 처리되었으므로 특히 그렇습니다. –