2012-06-21 4 views
5

이전 응용 프로그램에서 생성 및 유지하는 SQL Server 데이터베이스와 작동하는 C# 응용 프로그램을 작성해야합니다. 응용 프로그램은 매년 새 테이블을 만들고 "year 속성"이 테이블 이름에 있습니다. 작성한 테이블의 수는 사용자가 응용 프로그램 내에서 작성한 "섹션"의 수에 따라 달라질 수 있습니다. 그래서 Cwx_DRyz (아주 자명 한 ...)와 같은 테이블을 사용해야합니다. 여기서 "wx"는 섹션이 될 수 있고 "yz"는 연도가 될 수 있습니다. 테이블 그룹의 예는 수 :런타임에 엔티티 맵을 다른 "알 수없는"테이블로 변경합니다.

C01_DR07

C01_DR08

C01_DR09

C02_DR08

C02_DR09

C03_DR06

C04_DR12

에게

그리고 이러한 모든 테이블은 예를 들어 클라이언트를 나타낼 수 있습니다. 그들은 다른 섹션과 몇 년 동안의 고객이지만 동일한 구조를 가진 고객입니다.

내 질문은 : 모든 테이블을 처리하고 런타임마다 매핑을 변경할 수 있습니까? 런타임 전에 테이블을 모르기 때문에 제목에 "unknown"이라고 표시됩니다.

내가 찾은 가장 유사한 질문은 Entity Framework map multiple tables to one entity이고 대답은 "구체적인 유형 상속 테이블"을 사용하는 것이지만 내 경우에는 유용하지 않습니다.

PS : EF 버전 4.3.1 및 VS2010

편집 : 테이블 ... 기본 키가없는 그들 대부분은 고유 값 (정수 또는 문자열)을 가지고 supossed있는 열을 가지고있다.

답변

4

"코드 우선"을 사용하는 경우 원하는대로 매핑을 만들 수 있습니다. 이것은 생성 한 매핑이 데이터베이스와 일치 할 때 기존 데이터베이스에서도 작동합니다.

그래서 컨텍스트를 만들 때마다 매핑 할 문자열 (tablename)을 만들 수 있습니다.

"첫 번째 코드"와 방법에 대한 일부 codesamples 당신은 시작할 수 :

DbContext를 :

public DbSet<YourEntity> YourEntities { get; set; } 
... 

// this is called when the db gets created and does the configuration for you => maybe not needed in your case 
protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    ConfigurationRegistrar configurationRegistrar = modelBuilder.Configurations; 

    new GeneralEntitiesConfiguration(configurationRegistrar); 
} 

GeneralEntitiesConfiguration 클래스의 구성을 처리하기 위해 사용하는 메신저처럼 보이는 도우미에 지나지 :

public class GeneralEntitiesConfiguration 
{ 
    public GeneralEntitiesConfiguration(ConfigurationRegistrar configurationRegistrar) 
    { 
     configurationRegistrar.Add(new YourEntityConfiguration()); 
     //and additional configurations for each entity, just to splitt it a bit and have it more read and maintenance able 
    } 
} 

YourEntityConfiguration 내가이 엔티티에 대한 모든 구성이 클래스는 다음과 같습니다

public class YourEntityConfiguration : EntityTypeConfiguration<YourEntity> 
{ 
    public YourEntityConfiguration() 
    { 
     ToTable("WhatEverYouLike"); // here you can do any magic to map this entity to a table, just make sure that your properties are mapped to the correct colums 
     Property(entity => entity.Id).HasColumnName("YouColumnName"); 

     //and here you also have to do the other configurations 
    } 
} 

응용 프로그램 시작시 (또는 처음 컨텍스트를 초기화하기 전에) 데이터베이스를 초기화해야합니다. 따라서 데이터베이스를 검사하고 차이점을 처리하는 초기화 프로그램을 사용할 수 있습니다. 거기에 "DropCreateDatabaseAlways"또는 "DropCreateDatabaseIfModelChanges"=> 같은 것들이 있습니다. 당신은 차이점을 그냥 무시하는 자신의 것을 만들어야합니다.

//before using the context the first time i'm calling, you can ignore the connection string 
DbContextInitializer.Init(conString); 

public static class DbContextInitializer 
{ 
    public static void Init (string connectionString) 
    { 
     Database.SetInitializer(new CreateDbThrowExceptionIfModelDiffersInitializer<SMDbContext>()); 

     using(var dbContenxt = new MyDbContext(connectionString)) 
     { 
      try 
      { 
       dbContenxt.Database.Initialize(true); 
      } 
      catch(DatabaseModelDiffersException diffException) 
      { 
       // some magic... 
      } 
      catch(Exception ex) 
      { 
       // TODO: log 
       throw; 
      } 
     } 
    } 

    public class CreateDbThrowExceptionIfModelDiffersInitializer<TContext> : IDatabaseInitializer<TContext> where TContext : DbContext 
    { 
     public void InitializeDatabase(TContext context) 
     { 
      using (new TransactionScope(TransactionScopeOption.Suppress)) 
      { 
       if (!context.Database.Exists()) 
        context.Database.Create(); 
      } 

      if (!context.Database.CompatibleWithModel(true)) 
      { 
       throw new DatabaseModelDiffersException("Database Model differs!"); 
      } 
     } 

     protected virtual void Seed(TContext context) 
     { 
      // create data if you like 
     } 
    } 

    // just an exception i'm using for later useage 
    public class DatabaseModelDiffersException : Exception 
    { 
     public DatabaseModelDiffersException(string msg) : base(msg) 
     {} 
    } 
} 

은 당신의 생각은 동적 테이블을 처리 할 수 ​​있습니다 가지고 희망 : 내 샘플에서 난 그냥 모델 다릅니다은 (내가 첫 번째 시도에 대한 scipts과 모델 변경을 처리하기 위해 원) 예외가 발생 하나를 만들 수 있습니다 엔티티 프레임 워크와 이름! 더 많은 질문이 있으면 그냥 물어보십시오.

+0

모든 사용자가 만든 모든 "엔티티"(테이블 세트)를 가지고 있지 않기 때문에 매핑이 데이터베이스와 일치 할 필요는 없습니다. 완전 일치해야합니까? 어쨌든, 저 샘플들을 고맙게 생각합니다. – CarlosJ

+0

주말에 게시하겠습니다! –

+0

감사합니다. 대단히 감사합니다. – CarlosJ

관련 문제