2012-06-21 15 views
5

मुझे एक सी # एप्लिकेशन लिखना है जो एक पुराने सर्वर द्वारा बनाए गए SQL सर्वर डेटाबेस के साथ काम करता है। एप्लिकेशन प्रत्येक वर्ष नई टेबल बनाता है और "वर्ष संपत्ति" तालिका के नाम पर है। उपयोगकर्ता द्वारा बनाई गई तालिकाओं की संख्या "अनुभाग" की संख्या के आधार पर भिन्न हो सकती है जिसे उपयोगकर्ता ने एप्लिकेशन के अंदर बनाया है। इसलिए, मुझे Cwx_DRyz (काफी आत्म व्याख्यात्मक ...) जैसे तालिकाओं के साथ काम करना है, जहां "wx" अनुभाग हो सकता है, और "yz" वर्ष होगा। तालिका के समूह का एक उदाहरण हो सकता है:रनटाइम पर किसी अन्य "अज्ञात" तालिका में इकाई मानचित्र बदलें

C01_DR07

C01_DR08

C01_DR09

C02_DR08

C02_DR09

C03_DR06

C04_DR12

+०१२३५१६४१०६१

और उन सभी तालिकाओं का प्रतिनिधित्व कर सकता है, उदाहरण के लिए, ग्राहक। वे विभिन्न वर्गों और वर्षों के ग्राहक होंगे, लेकिन एक ही संरचना वाले ग्राहक।

मेरा प्रश्न है: क्या मेरे पास उन सभी तालिकाओं को संभालने के लिए क्लाइंट इकाई हो सकती है और मैपिंग को रनटाइम पर एक से दूसरे में बदल सकती है? शीर्षक "अज्ञात" कहता है क्योंकि मुझे रनटाइम से पहले टेबल नहीं पता है।

मुझे मिला है कि सबसे समान प्रश्न Entity Framework map multiple tables to one entity है और उत्तर "तालिका प्रति कंक्रीट प्रकार विरासत" का उपयोग करना है, लेकिन यह मेरे मामले के लिए उपयोगी नहीं है।

पुनश्च: एफई संस्करण 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 विन्यास को संभालने के लिए उपयोग कर एक वर्ग im, एक सहायक जो की तरह दिखता है से ज्यादा कुछ नहीं है :

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 एक वर्ग जहां मैं इस इकाई के लिए सभी विन्यास है:

012,
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

संबंधित मुद्दे