2017-09-19 8 views
1

명명 규칙과 이해를 결합하여 어려움을 겪고있는 것 같습니다.다 대다 관계를 완전히 코드 나 데이터베이스로 업데이트하지 말 것.

나는 데이터베이스를 상속 받았으며 "데이터베이스 우선"워크 플로우를 제대로 수행 할 수없는 MVC 사이트를 구축하고 있습니다. 결국 나는 수동으로 컨텍스트 클래스를 구축하고 행복하게 일 해왔다.

이제는 기존의 여러 엔터티 (many-to-many)에 관계가있는 엔터티를 추가 할 수없는 상황에 처해 있습니다. 이 같은 (이 질문에 대한 간체)

내 데이터베이스 외모 :

public virtual DbSet<ListItem> ListItems { get; set; } 

내가 일부를 사용하는 경우 :

ListItem  Option  OptionListItems 
======  ======  =============== 
Id   Id   ListItem_Id 
Name   Name   Option_Id 

내 컨텍스트 내 많은 ListItems을 모두 얻을 수있는 속성이 포함 LINQ, 나는 다음과 같은 것을하고 item은 반환되고 many-to-many 관계가 만족되고 ListItem 안에 Option의 목록을 얻는다 :

사실, 위의 쿼리를 실행하려고 할 때 데이터베이스에서 수동으로 상호 참조 테이블을 구성해야했으며 예외는 내가 dbo.OptionListItems이라는 개체가 없다고 말했습니다. 그래서 우리는 우리 모두가 선하다고 생각했습니다.

지금 나는 새로운 ListItem을 작성하고 하나 이상의 기존Option에 연결해야하고 나는 손실에 있어요. 나는 그것이 실패 listItem.Options.Add(...)를 호출하는 나의 새로운 ListItem 분리, 그리고 시도를 만들었습니다,하지만 난 특정 Option에 대한 참조를 가져하려고 option.ListItems.Add(...)을하려고하면 나는 또한 동일한 예외를 일단

.

오류는 재미있는의 종류와 반대 테이블 이름은 내가 무엇을하는 것입니다 :

{"Invalid object name 'dbo.ListItemOptions'."} 

나는 그것이 내 상황에 유형과 속성을 구축 EF의 성미에가는 것으로 의심 직접 다음과 같이 상호 참조 테이블에 액세스하십시오.

public virtual DbSet<OptionListItem> OptionListItems { get; set; } 

그러나 완전히 새로운 관계를 만드는 패턴에 당황 스럽습니다.

+0

를 제어해야하는 경우가 DB 첫번째 물건을 찢어하지만, 코드 첫 번째의 방법 확실하지 대다 당신이 [이]처럼 유창 맵 코드가 필요합니다 (HTTP : //www.entityframeworktutorial .net/code-first/configure-many-to-many-relationship-in-code-first.aspx) (하단 근처). –

+0

그래, 이상한 상황이야. DB와 일부 수작업으로 만들어진 POCO가 있었기 때문에 스캐 폴딩이나 마이그레이션에 의존하는 대신 수동으로 양측에 비트를 추가했습니다. 매핑을 만들려고하기 전에 (내가 그 게시물을 보았지만 가장 좋은 접근 방법이라고 확신하지 못했습니다), 사용하기 좋은 패턴은 무엇입니까? 내'ListItem'과'.Add'를 Options 컬렉션에 가져 가면 매핑이 제대로 작동할까요? – Neil

답변

0

선언적으로 작동하는 (many-to-many) 작업이 있습니다. 의사 :이 전체 관계를 만들어야합니다

public class ListItem 
{ 

    public ListItem() 
    { 
     this.RelatedOptions = new HashSet<OptionListItems>(); 
    } 

    [Key] 
    public int Id {get; set;} 
    public string Name {get; set;} 
    public virtual ICollection<OptionListItems> RelatedOptions {get; set;} 
} 

public class Option 
{ 
    public Ortion() 
    { 
     this.RelatedItems = new HashSet<OptionListItems>(); 
    } 

    [Key] 
    public int Id {get; set;} 
    public string Name {get; set;} 
    public virtual ICollection<OptionListItems> RelatedItems {get; set;} 
} 


public class OptionListItems 
{ 
    [Key] 
    public int Id {get; set;} 

    [Column("ListItemId", Order = 1)] 
    [ForeignKey("ParentListItem")] 
    public int ListItemId {get; set;} 

    [Column("OptionId", Order = 2)] 
    [ForeignKey("ParentOption")] 
    public int OptionId {get; set;} 

    public virtual ListItem ParentListItem {get; set;} 
    public virtual Option ParentOption {get; set;} 
} 

선언적

+0

고마워요. 저는 이미 매우 비슷한 모델을 가지고 있었지만, 적어도이 게시물은 제가 그것을 검증하는데 도움이되었습니다. – Neil

0

신용 올바른 방향으로 날을 가리키는 스티브 그린로 이동합니다. 테이블은 내가 규칙에 따라 만들어졌고 WorkItem.Include(p => p.Options)으로 쿼리했을 때 작동했지만 업데이트를 시도하면 규칙이 무너지는 것 같습니다. 이유는 모르겠지만 매핑 테이블의 구성은 쿼리 할 때 <Entity1>+<Entity2>+s 인 것 같습니다. 그러나 업데이트 할 때 <Entity2>+<Entity1>+s ...

FluentAPI를 사용하여 엔티티 간의 특정 매핑을 만들었고 상호 참조 테이블과 쿼리 및 업데이트 작업을 모두 수행했습니다.

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<ListItem>() 
      .HasMany<Option>(s => s.Options) 
      .WithMany(c => c.ListItems) 
      .Map(cs => 
      { 
       cs.MapLeftKey("ListItem_Id"); 
       cs.MapRightKey("Option_Id"); 
       cs.ToTable("OptionListItems"); 
      }); 
    }