2012-04-07 4 views
1

코드가있는 EF를 약간 시도하고 있는데, 내가 잘못 생각한 부분을 알아낼 수는 없습니다. 단지 내 자신의 예일뿐입니다. 나는 아이디어가별로 없어서 내가 잘못 가고있는 곳을 꾸미고 싶습니다.TPH Simple Config/Discriminator 문제

처음으로 위치를 나타내는 POCO 클래스 - 위치는 RadioStation 또는 판매자가 될 수 있습니다. 나는 추가 필드를 추가하지 않았다. (나중에 올 것이다.) 그래서 지금은 TPH를 단순한 설정으로 만들 수있다.

namespace EFDataClasses.Entities 
{ 

    public class RadioStation : Location 
    { 
    public RadioStation() 
    { 
    } 

    } 

    public class Merchant : Location 
    { 
    public Merchant() 
    { 
    } 
    } 


    public class Location 
    { 
    public Location() 
    { 

    } 

public int Loc_ID { get; set; } 
public string Loc_Code { get; set; } 
public string Loc_Name { get; set; } 
public string Loc_Type {get;set;} 

} 
} 

다음 설정 클래스 : 여기

namespace EFDataClasses.Mapping 
{ 


    public class LocationMap : EntityTypeConfiguration<Location> 
    { 
    public LocationMap() 
    { 
     // Primary Key 
     this.HasKey(t => t.Loc_ID); 

     // Properties 
     this.Property(t => t.Loc_ID) 
      .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 

     // Properties 
     this.Property(t => t.Loc_Code) 
      .IsRequired() 
      .HasMaxLength(50); 

     this.Property(t => t.Loc_Name) 
      .IsRequired() 
      .HasMaxLength(50); 


     this.Property(t => t.Loc_ID).HasColumnName("Loc_ID"); 
     this.Property(t => t.Loc_Code).HasColumnName("Loc_Code"); 
     this.Property(t => t.Loc_Name).HasColumnName("Loc_Name"); 

     //my discriminator property 
     this.Property(t => t.Loc_Type).HasColumnName("Loc_Type").HasColumnType("varchar").HasMaxLength(50).IsRequired(); 

     // Table & Column Mappings 
     this.Map(m => 
     { 
     m.ToTable("Location"); 
     m.Requires("Loc_Type").HasValue("Location"); 
     } 
     ) 
     .Map<RadioStation>(m => 
     { 
      m.ToTable("Location"); 
      m.Requires("Loc_Type").HasValue("RadioStation"); 
     } 
     ) 
     .Map<Merchant>(m => 
     { 
      m.ToTable("Location"); 
      m.Requires("Loc_Type").HasValue("Merchant"); 
     } 
     ) 
     ; 



    } 
    } 
} 

컨텍스트입니다 .. 라디오 방송국을 추가하려고

namespace EFDataClasses 
{ 
    public class MyContext : DbContext 
    { 
    static MyContext() 
    { 
     Database.SetInitializer<MyContext>(new DropCreateDatabaseAlways<MyContext>()); 
    } 

    public DbSet<EFDataClasses.Entities.Location> Locations {get; set;} 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Configurations.Add(new LocationMap()); 
    } 
    } 
} 

마지막으로 프로그램 클래스

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace EFConsole 
{ 
    class Program 
    { 
    static void Main(string[] args) 
    { 

     var db = new EFDataClasses.MyContext(); 
     db.Locations.Add(new EFDataClasses.Entities.RadioStation() { Loc_Name = "Radio Station Name 1", Loc_Code = "RD1" }); 
     int chngs = db.SaveChanges(); 
     System.Diagnostics.Debugger.Break(); 

    } 
    } 
} 

내가 잘못했다는 오류 loc_Type에 유효성 검사 오류가 발생하여 필수 필드임을 나타냅니다. 여기 내 인상은 적절한 유형을 선택할 때 EF가이를 채울 것이라는 것입니다. 그리고 모든 독서가 그것을 지원합니다.

내가 적절한 위치 유형 추가 할 경우

- EF 나에게 또 다른 오류를 줄을 ....

arggghhh!

결국 나는 위치 추상을 만들고 싶습니다. 그렇다면 hasvalue ("Location")을 삭제할 수 있습니까?

나는 여기로 나아가고 싶지만, 내가 잘못한 점은 궁금하다. 감사!

답변

0

문제는 열을 TPH 매핑의 판별 자로 사용할 때 해당 열을 클래스의 속성에 매핑 할 수 없다는 것입니다. 이것은 EF가 이제 .NET 클래스 유형에 따라 해당 열의 값을 제어하기 때문입니다. 그래서 당신은 위치 컬럼에 Loc_Type 속성의 매핑을 수행이 줄을 제거해야합니다 :

// Remove this line: 
this.Property(t => t.Loc_Type).HasColumnName("Loc_Type").HasColumnType("varchar").HasMaxLength(50).IsRequired(); 

당신은 판별 자 컬럼 등 명시 적 열 유형, 크기, 당신은 수 지정해야합니다 (또는 할) 경우 Map 호출에서 그렇게하십시오. 예 :

Map(m => 
{ 
    m.ToTable("Location"); 
    m.Requires("Loc_Type") 
     .HasValue("Location") 
     .HasColumnType("varchar") 
     .HasMaxLength(50) 
     .IsRequired(); 
} 

위치 유형을 나타내는 클래스에는 속성이 필요하지 않습니다. 당신이 Loc_Type의 문자열 값에 상당하고 싶지 않는 경우에 당신은 위치에 같은 것을 사용할 수 있습니다

public virtual string Loc_Type 
{ 
    get { return "Location"; } 
} 

그런 다음 다른 클래스에 우선합니다. 예 :

public override string Loc_Type 
{ 
    get { return "RadioStation"; } 
} 

나머지 코드는 괜찮습니다.

+0

나는 당신이 여기서 올바른 방향으로 가고 있다고 생각하지만, 나는 왜 EF에 매핑 파일에 각 서브 클래스의 값을 알려주고 나서 Loc_Type의 특성을 오버라이드해야하는지 혼란 스럽다. 나는 판별 자 필드의 이름과 크기를 관례에 따른 구성을 사용하여 제어하기 만하면됩니다. – codeputer

+0

Loc_Type 속성을 재정의 할 필요가 없습니다. 그 재산에 대한 가치를 원한다면 나는 그걸 보여 주려했다. 판별 자 필드의 크기를 구성하려면 맵 호출에서 판별 자 필드의 크기를 지정하십시오. 나는 이것을 보여줄 나의 대답을 업데이트 할 것이다. –

+0

여기 내 주요 혼란이 FK 분야에 기여하고 유창한 API를 사용하여 관계를 형성했다는 것을 알았습니다. 이 경우 클래스의 FK 필드를 매핑하지만 discriminator는 그렇지 않습니다. 나는 이런 이유로 판별자를 수업에서 삭제하는 것을 결코 생각하지 못했습니다. 이것이 API 디자인의 불일치라고 생각됩니다. 어떻게 생각해? – codeputer

1

저는 여러분이 조금 복잡해 졌다고 생각합니다. CF 주변에서는 위험합니다.
코드 우선은 작동하고 테스트 된 패턴을 고수해야합니다. 그렇지 않으면 사물과 구문을 혼합하면 곧 문제가 발생할 것입니다.

먼저 Loc_Type을 매핑하고 LocerType이 필요한 이유는 무엇입니까? 클래스 모델을 의미합니까? 그건 불필요한 것입니다. 여러분은 여러분의 '클래스'타입으로 그것을 얻을 것이고, 클래스 타입은 discriminator이고, 그 반대도 마찬가지입니다.

그리고 그게 오류라고 생각하니, 공급하거나 '매핑에서 열을 떨어 뜨리는 것'이든 아니든간에.

그럼 그냥 'Location'에서 삭제하면 문제가 없습니다. 또한 Db를 이해하고 상대방이 사용하는 등 괜찮은 경우가 아니라면 대부분의 경우 discriminator를 지정할 필요가 없습니다.

당신이 추상화를 원한다면, Location은 정상적으로 처리 할 수 ​​있습니다. 그리고 정상적으로 처리되었으므로 맵핑에서 삭제할 수 있다고 생각합니다. 단지 '실제 구현 된'클래스 만 맵핑되어 '인스턴스화'될 수 있습니다.

그리고 마지막으로, TPH는 여러 가지 이유로 가장 '운 좋은'해결책이 아니며, TPT, TPC 모두가 훨씬 더 '유동적'인 것으로 생각합니다. '자식 클래스'속성을 null이 아니거나 등으로 가질 수 없습니다. 거기에 게시물이 있습니다.

희망이 도움이됩니다.

편집 : '숨겨진'판별자를 제어하려면 I think을 시도하고 수동으로 해당 열의 migration file을 조정하여 크기 등을 설정하십시오. 중요하다면 (코드에서 올바른 값을 선택해야합니다. 나는 거기에서 추측한다). 작동해야하는 일의 의미에 중요한 것을 변경하지 않으면.

+0

NSGaga - 수업 측면에서 여러분이 말하는 것을 듣지만, 관례와 필요성에 관계없이 코드는 먼저 Discriminator라는 열을 추가합니다. 필드의 매핑에서 Discriminator 필드의 이름과 크기를 제어하기 만하면됩니다. 이 필드를 비공개로 설정할 수 있다면 (더 좋을까요?), 더 좋습니다. 이 기술을 채택하고 싶습니다만, 지금 당장 DB 디자인을 선호하고, 주로 Table-per-Type을 고수하고 있습니다! – codeputer

+0

내가 생각하는 마이그레이션 파일을 수동으로 조정하여 세부 사항을 제어 할 수 있습니다. 그 트릭을 수행 할 수 있습니다. '개인 정보'가 제대로 작동하는지 확신 할 수 없습니다. 매핑을 매핑하면 매핑을 취소 할 필요가 있다고 생각합니다. 그리고 @Arthur는 이것을 확인하는 것과 똑같은 것을 말했습니다, 그는 MS로부터이 물건을 다루는 사람입니다. 그래서 나는 그가 추측하고 있음을 알아야합니다. – NSGaga

+0

table-per-type에 대해 언급합니다. EF Code First로 이것을 할 수도 있습니다. TPH, TPT 또는 TPC (concrete per class)를 할 수 있습니다. 다음은 옵션을 설명하고이를 수행하는 방법을 설명하는 훌륭한 일련의 게시물입니다. http://weblogs.asp.net/manavi/archive/2010/12/24/inheritance-mapping-strategies-with-entity-framework-code- first-ctp5-part-1-table-per-hierarchy-tph.aspx –