2012-06-21 40 views
5

Tôi phải viết một ứng dụng C# hoạt động với cơ sở dữ liệu máy chủ SQL được tạo và được duy trì bởi một ứng dụng cũ. Ứng dụng tạo bảng mới mỗi năm và thuộc tính "năm" nằm trong tên bảng. Số lượng bảng mà nó tạo có thể khác nhau tùy thuộc vào số "phần" mà người dùng đã tạo bên trong ứng dụng. Vì vậy, tôi phải làm việc với các bảng như Cwx_DRyz (khá tự giải thích ...), trong đó "wx" có thể là phần, và "yz" sẽ là năm. Một ví dụ về nhóm của bảng có thể là:Thay đổi bản đồ thực thể sang bảng "không xác định" khác tại thời gian chạy

C01_DR07

C01_DR08

C01_DR09

C02_DR08

C02_DR09

C03_DR06

C04_DR12

Và tất cả các bảng đó có thể đại diện, ví dụ như khách hàng. Họ sẽ là khách hàng từ các phần và năm khác nhau, nhưng khách hàng có cùng cấu trúc.

Câu hỏi của tôi là: Tôi có thể có một thực thể Khách hàng để xử lý tất cả các bảng đó và thay đổi ánh xạ từ cái này sang cái khác trong thời gian chạy không? Tiêu đề nói "không xác định" vì tôi không biết các bảng trước khi chạy.

Câu hỏi tương tự nhất mà tôi đã tìm thấy là Entity Framework map multiple tables to one entity và câu trả lời là sử dụng "Bảng mỗi loại thừa kế kiểu bê tông", nhưng nó không hữu ích cho trường hợp của tôi.

PS: EF phiên bản 4.3.1 và VS2010

EDIT: Các bảng không có khóa chính ... Hầu hết trong số họ có cột có supossed có giá trị duy nhất (số nguyên hoặc chuỗi).

Trả lời

4

Nếu bạn sử dụng "mã đầu tiên", bạn có thể tạo một ánh xạ như bạn muốn. Điều này cũng làm việc với các cơ sở dữ liệu hiện có khi ánh xạ mà bạn đã tạo khớp với cơ sở dữ liệu.

Vì vậy, bất cứ khi nào bạn tạo ngữ cảnh, bạn có thể tạo chuỗi (tablename) bạn muốn ánh xạ tới.

Một số codesamples cho "mã đầu tiên" và làm thế nào bạn có thể bắt đầu:

Các 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 là một im lớp sử dụng để xử lý các cấu hình, không có gì hơn một helper trông giống như :

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 là lớp mà tôi có tất cả các cấu hình cho thực thể này:

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 
    } 
} 

Khi khởi động ứng dụng (hoặc trước khi bạn khởi tạo ngữ cảnh lần đầu tiên), bạn phải khởi tạo cơ sở dữ liệu. Vì vậy, bạn có thể sử dụng một trình khởi tạo để kiểm tra cơ sở dữ liệu và xử lý sự khác biệt. Xây dựng trong đó có những thứ như "DropCreateDatabaseAlways" hoặc "DropCreateDatabaseIfModelChanges" => bạn sẽ cần phải tạo riêng của bạn mà chỉ bỏ qua bất kỳ sự khác biệt.Trong mẫu của tôi, tôi đã tạo ra một trong đó chỉ ném một ngoại lệ khi khác với mô hình (i muốn để xử lý thay đổi mô hình với scipts cho lần thử đầu tiên):

//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) 
     {} 
    } 
} 

Hy vọng bạn đã có một ý tưởng của bạn có thể xử lý bảng năng động tên với khung thực thể! Nếu có thêm câu hỏi chỉ cần hỏi;)

+0

Ánh xạ không cần thiết phù hợp với cơ sở dữ liệu vì không phải tất cả người dùng đều có tất cả "thực thể" (bộ bảng) được tạo. Có bắt buộc phải hoàn thành một trận đấu không? Dù sao, tôi sẽ đánh giá cao những mẫu đó. – CarlosJ

+0

Tôi sẽ đăng nó vào cuối tuần! –

+0

Ok, cảm ơn bạn rất nhiều. – CarlosJ

Các vấn đề liên quan