2012-10-10 17 views
7

मैं एक आधार dbcontext कि सभी आम संस्थाओं कि हमेशा कई परियोजनाओं में पुन: उपयोग किया जाएगा, पृष्ठ, उपयोगकर्ता भूमिकाओं, नेविगेशन आदिएफई कोड पहले: विरासत में मिला dbcontext दो डेटाबेस

की तरह होता है बनाने के लिए कोशिश कर रहा हूँ बनाता है ऐसा करने में मेरे पास एक कॉन्टेक्स्टबेस क्लास है जो डीबीकॉन्टेक्स्ट को विरासत में लेती है और मैं चाहता हूं कि सभी डीबीसेट्स को परिभाषित करता है। तब मेरे पास एक संदर्भ वर्ग है जो ContextBase को विरासत में लेता है जहां मैं प्रोजेक्ट विशिष्ट डीबीसेट्स को परिभाषित करता हूं। कक्षाएं इस प्रकार परिभाषित कर रहे हैं:

public class ContextBase : DbContext 
{ 
    public virtual DbSet<User> Users { get; set; } 
    //more sets 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Configurations.Add(new UsersConfiguration()); 
     //add more configurations 
    } 
} 


public class Context : ContextBase 
{ 
    public DbSet<Building> Buildings { get; set; } 
    //some more project specific sets 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 
     modelBuilder.Configurations.Add(new BuildingsConfiguration()); 
     //add more project specific configs 
    } 
} 

मेरी Global.asax में:

Database.SetInitializer(new MigrateDatabaseToLatestVersion<Context, Configuration>()); 

जहां एक वर्ग के लिए विन्यास referes DbMigrationsConfiguration इनहेरिट और बीज विधि अधिभावी।

दो संदर्भ वर्गों को एक ही नामस्थान में परिभाषित किया गया है, लेकिन क्रॉस असेंबली (ताकि मैं परियोजना विशिष्ट कोड को छूए बिना कई मौजूदा परियोजनाओं में बेस प्रोजेक्ट अपडेट कर सकूं) - सुनिश्चित नहीं है कि यह प्रासंगिक है या नहीं।

मेरी समस्या: इस कोड चल रहा है, यह ठीक काम करता है, लेकिन जब डेटाबेस में देख, यह वास्तव में दो अलग-अलग डेटाबेस बनाता है !! इनमें से सभी मूल इकाई सारणीयां और एक दोनों को आधार आधार और कस्टम टेबल शामिल हैं। सीआरयूडी ऑपरेशंस केवल कस्टम संस्करण (जो स्पष्ट रूप से मैं चाहता हूं) पर किया जाता है, लेकिन यह दूसरे की स्कीमा क्यों बनाता है?

किसी भी मदद की सराहना की है, धन्यवाद!

अद्यतन:

निम्नलिखित कोड है कि मैं क्या साथ समाप्त हो गया है। यह आदर्श नहीं है, लेकिन यह काम करता है। मैं अभी भी इसे सुधारने के तरीकों पर फीडबैक प्राप्त करना पसंद करूंगा, लेकिन इस बीच में मुझे उम्मीद है कि यह प्रक्रिया को आगे बढ़ाने में मदद करेगा। मैं वास्तव में यह करने की सिफारिश नहीं करता! यह बेहद त्रुटि प्रवण है और डीबग करने के लिए बहुत निराशाजनक है। मैं इसे देखने के लिए केवल यह पोस्ट कर रहा हूं कि यह प्राप्त करने के लिए कोई बेहतर विचार या कार्यान्वयन है या नहीं।

एक (लेकिन केवल एकमात्र) मुद्दा अभी भी मौजूद नहीं है कि एमवीसी विचारों को मैन्युअल रूप से परियोजनाओं में जोड़ा जाना है। मैंने इसे Nuget पैकेज में जोड़ा है, लेकिन वीएसएस को टीएफएस से कनेक्ट होने पर कई फाइलों के साथ एक न्यूज पैकेज लागू करने में 2 से 3 घंटे लगते हैं। कुछ और काम और कस्टम व्यू इंजन के साथ विचारों को प्रीकंपिल्ड किया जा सकता है (http://blog.davidebbo.com/2011/06/precompile-your-mvc-views-using.html)।

समाधान बेस फ्रेमवर्क परियोजनाओं और कस्टम परियोजनाओं में विभाजित है (प्रत्येक श्रेणी में अपने मॉडल और भंडार पैटर्न शामिल हैं)। फ्रेमवर्क परियोजनाओं को एक नुजेट पैकेज में पैक किया जाता है और फिर किसी भी प्रोजेक्ट में स्थापित किया जाता है जो किसी भी प्रोजेक्ट की सामान्य कार्यक्षमता जैसे उपयोगकर्ता, भूमिका और अनुमति प्रबंधन, सामग्री प्रबंधन इत्यादि (जिसे अक्सर बॉयलर प्लेट के रूप में जाना जाता है) को आसानी से जोड़ा जा सकता है कोई नई परियोजनाएं यह बॉयलरप्लेट के किसी भी मौजूदा कस्टम प्रोजेक्ट में माइग्रेट किए जाने के किसी भी सुधार की अनुमति देता है।

कस्टम डाटाबेस प्रारंभकर्ता:

public class MyMigrateDatabaseToLatestVersion : IDatabaseInitializer<Context> 
{ 
    public void InitializeDatabase(Context context) 
    { 
     //create the base migrator 
     var baseConfig = new FrameworkConfiguration(); 
     var migratorBase = new DbMigrator(baseConfig); 
     //create the custom migrator 
     var customConfig = new Configuration(); 
     var migratorCustom = new DbMigrator(customConfig); 

     //now I need to check what migrations have not yet been applied 
     //and then run them in the correct order 
     if (migratorBase.GetPendingMigrations().Count() > 0) 
     { 
      try 
      { 
       migratorBase.Update(); 
      } 
      catch (System.Data.Entity.Migrations.Infrastructure.AutomaticMigrationsDisabledException) 
      { 
       //if an error occured, the seed would not have run, so we run it again. 
       baseConfig.RunSeed(context); 
      } 
     } 
     if (migratorCustom.GetPendingMigrations().Count() > 0) 
     { 
      try 
      { 
       migratorCustom.Update(); 
      } 
      catch (System.Data.Entity.Migrations.Infrastructure.AutomaticMigrationsDisabledException) 
      { 
       //if an error occured, the seed would not have run, so we run it again. 
       customConfig.RunSeed(context); 
      } 
     } 
    } 
} 

फ्रेमवर्क के डीबी माइग्रेशन विन्यास:

public class FrameworkConfiguration: DbMigrationsConfiguration<Repository.ContextBase> 
{ 
    public Configuration() 
    { 
     AutomaticMigrationsEnabled = false; 
    } 

    public void RunSeed(Repository.ContextBase context) 
    { 
     Seed(context); 
    } 

    protected override void Seed(Repository.ContextBase context) 
    { 
     // This method will be called at every app start so it should use the AddOrUpdate method rather than just Add. 

     FrameworkDatabaseSeed.Seed(context); 
    } 
} 

कस्टम परियोजना की डीबी माइग्रेशन विन्यास:

public class Configuration : DbMigrationsConfiguration<Repository.Context> 
{ 
    public Configuration() 
    { 
     AutomaticMigrationsEnabled = false; 
    } 

    public void RunSeed(Repository.Context context) 
    { 
     Seed(context); 
    } 

    protected override void Seed(Repository.Context context) 
    { 
     // This method will be called at every app start so it should use the AddOrUpdate method rather than just Add. 

     CustomDatabaseSeed.Seed(context); 
    } 
} 

कस्टम DbContext

//nothing special here, simply inherit ContextBase, IContext interface is purely for DI 
public class Context : ContextBase, IContext 
{ 
    //Add the custom DBsets, i.e. 
    public DbSet<Chart> Charts { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 

     //Assign the model configs, i.e. 
     modelBuilder.Configurations.Add(new ChartConfiguration()); 
    } 
} 

फ्रेमवर्क DbContext:

//again nothing special 
public class ContextBase: DbContext 
{ 
    //example DbSet's 
    public virtual DbSet<Models.User> Users { get; set; } 
    protected override void OnModelCreating(DbModelBuilder modelBuilder); 
} 

Global.asax AppStart में:

 //first remove the base context initialiser 
     Database.SetInitializer<ContextBase>(null); 
     //set the inherited context initializer 
     Database.SetInitializer(new MyMigrateDatabaseToLatestVersion()); 

web.config में:

<connectionStrings> 
    <!--put the exact same connection string twice here and name it the same as the base and overridden context. That way they point to the same database. --> 
    <add name="Context" connectionString="Data Source=.\SQLEXPRESS; Initial Catalog=CMS2013; Integrated Security=SSPI;MultipleActiveResultSets=true;" providerName="System.Data.SqlClient"/> 
    <add name="ContextBase" connectionString="Data Source=.\SQLEXPRESS; Initial Catalog=CMS2013; Integrated Security=SSPI;MultipleActiveResultSets=true;" providerName="System.Data.SqlClient"/> 
</connectionStrings> 
+0

बेस क्लास में कनेक्शन स्ट्रिंग सेट करने का प्रयास करें (या इसे माता-पिता से पास करें) यानी सार्वजनिक संदर्भ बॉक्स(): आधार ("MyConnection") –

+1

क्या आप ContextBase से आधार भी कॉल कर रहे हैं? यदि आप अधिक कॉन्फ़िगरेशन जोड़ते हैं, तो क्या यह प्रत्येक कॉन्फ़िगरेशन के लिए डेटाबेस बनाता है? कॉन्फ़िगरेशन जोड़ने का प्रयास करें, फिर बेस को कॉल करें। ऑनमोडेल क्रिएटिंग। – MrFox

+1

क्या आपने कभी 'कॉन्टेक्स्टबेस' संदर्भ सीधे बनाया है? ('नया ContextBase()') यदि आप करते हैं, और आप नहीं चाहते हैं, तो आप यह सुनिश्चित करने के लिए 'ContextBase' 'abstract' बना सकते हैं कि संकलक फ़्लैग ऐसा करने का प्रयास करता है। – hvd

उत्तर

5

(टिप्पणियों से)

आप एक सामान्य प्रकार तर्क के रूप में जाहिरा तौर पर ContextBase साथ एक सामान्य विधि में new T() रूप ContextBase वस्तुओं बना रहे हैं सीधे,, इसलिए ContextBase के लिए किसी भी initialisers भी चलाते हैं। ContextBase ऑब्जेक्ट्स को बनाने से रोकने के लिए (अगर इसे सीधे तत्काल नहीं किया जाना चाहिए, यदि व्युत्पन्न संदर्भ हमेशा उपयोग किया जाना चाहिए), तो आप कक्षा को abstract के रूप में चिह्नित कर सकते हैं।

3

आपका ContextBase एक प्रारंभकर्ता भी हो रहा है .. आप इसे

द्वारा हटा सकते हैं
Database.SetInitializer<ContextBase>(null); 
+0

धन्यवाद, मुझे उपरोक्त @ एचवीडी की टिप्पणी के अनुसार समाधान मिला है, लेकिन इस जवाब ने वास्तव में भी मेरी मदद की। +1 – hofnarwillie

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