2016-09-06 11 views
8

मैं अपनी परियोजना में एंटीटी-फ्रेमवर्क को लागू करने का प्रयास करता हूं! मेरा प्रोजेक्ट प्लगइन आधारित है इसलिए मुझे नहीं पता कि मुझे किस ऑब्जेक्ट को डेटाबेस में सहेजना है।इकाई-फ्रेमवर्क ऑटो अपडेट

मैं यह इतना लागू कर दिया है:

public class DatabaseContext : DbContext 
{ 
    public DatabaseContext() : base() 
    { 
     Database.Initialize(true); 
    } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     foreach(PluginDto plugin in BackendContext.Current.PluginManager._plugins) { 
      foreach(Type obj in plugin.plugin.getPluginDatabaseObjects()) 
      { 
       Type typ = typeof(EntityTypeConfiguration<>).MakeGenericType(obj); 

       List<MethodInfo> l = modelBuilder.GetType().GetMethods().ToList<MethodInfo>(); 

       MethodInfo m_Entitiy = modelBuilder.GetType().GetMethod("Entity").MakeGenericMethod(new Type[] { obj }); 
       var configObj = m_Entitiy.Invoke(modelBuilder, null); 

       MethodInfo m_ToTable = configObj.GetType().GetMethod("ToTable", new Type[] { typeof(String) }); 
       m_ToTable.Invoke(configObj, new object [] { obj.Name }); 
      } 
     } 

     base.OnModelCreating(modelBuilder); 
    } 

} 

लेकिन मैं इस अपवाद मिलता है, जब मैं एक परिवर्तन दे:

The model backing the 'DatabaseContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).

यह त्रुटि को पूरी तरह से तार्किक है। डेटाबेस सिंक से बाहर है, लेकिन मुझे अपडेट कैसे मिलेगा? मैंने इसके बारे में कुछ पढ़ा है:

var config = new DbMigrationsConfiguration<MyContext> { AutomaticMigrationsEnabled = true }; 
var migrator = new DbMigrator(config); 
migrator.Update(); 

लेकिन मुझे नहीं पता कि यह कैसे और कहां सही तरीके से उपयोग करें! बहुत बहुत धन्यवाद!

EDIT1: जब मैं करने की कोशिश: सक्षम-माइग्रेशन -EnableAutomaticMigrations

मैं यह त्रुटि आई:

System.NullReferenceException: Object reference not set to an instance of an object. 
    at SOM.Backend.database.DatabaseContext.OnModelCreating(DbModelBuilder modelBuilder) in C:\Users\Flo\Documents\Visual Studio 2015\Projects\SOM\Backend\BackendService\BackendService\database\DatabaseContext.cs:line 26 
    at System.Data.Entity.Internal.LazyInternalContext.CreateModelBuilder() 
    at System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext) 
    at System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input) 
    at System.Data.Entity.Internal.LazyInternalContext.InitializeContext() 
    at System.Data.Entity.Internal.LazyInternalContext.MarkDatabaseInitialized() 
    at System.Data.Entity.Database.Initialize(Boolean force) 
    at SOM.Backend.database.DatabaseContext..ctor() in C:\Users\Flo\Documents\Visual Studio 2015\Projects\SOM\Backend\BackendService\BackendService\database\DatabaseContext.cs:line 21 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
    at System.Data.Entity.Infrastructure.DbContextInfo.CreateInstance() 
    at System.Data.Entity.Infrastructure.DbContextInfo..ctor(Type contextType, DbProviderInfo modelProviderInfo, AppConfig config, DbConnectionInfo connectionInfo, Func`1 resolver) 
    at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration, DbContext usersContext, DatabaseExistenceState existenceState, Boolean calledByCreateDatabase) 
    at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration) 
    at System.Data.Entity.Migrations.Design.MigrationScaffolder..ctor(DbMigrationsConfiguration migrationsConfiguration) 
    at System.Data.Entity.Migrations.Design.ToolingFacade.ScaffoldRunner.Run() 
    at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate) 
    at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate) 
    at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner) 
    at System.Data.Entity.Migrations.Design.ToolingFacade.ScaffoldInitialCreate(String language, String rootNamespace) 
    at System.Data.Entity.Migrations.EnableMigrationsCommand.<>c__DisplayClass2.<.ctor>b__0() 
    at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command) 

EDIT2:

<connectionStrings> 
    <add name="DatabaseContext" providerName="System.Data.SqlServerCe.4.0" connectionString="Data Source=SOM_db.sdf;Max Database Size=1024" /> 
    </connectionStrings> 
+0

ऐसा लगता है कि आप अपनी दृढ़ता परत के लिए गलत टूल का उपयोग कर रहे हैं। क्या आपने नोएसक्यूएल समाधान के बारे में सोचा था? –

+0

@raderick यह एक विकल्प नहीं है .... – Flo

+0

क्या आपने अपडेट-डाटाबेस-वेरबोज का उपयोग करके पावरहेल या न्यूज पैकेज मैनेजर कंसोल को अपडेट करने का प्रयास किया है? इसके अलावा, माइग्रेशन द्वारा बनाई गई एक नई तालिका पर इंगित शून्य संदर्भ है? – GaelSa

उत्तर

5

आप क्या पूछ रहे हैं, लेकिन कुछ सीमाओं के साथ।

समाधान:

पहले, निर्माता से

Database.Initialize(true); 

को हटा दें। कन्स्ट्रक्टर को कई बार, कहा जाता है जिसमें माइग्रेशन शामिल हैं।

दूसरा, इस

internal sealed class DataContextConfiguration : DbMigrationsConfiguration<DataContext> 
{ 
    public DataContextConfiguration() 
    { 
     AutomaticMigrationsEnabled = true; 
     AutomaticMigrationDataLossAllowed = true; 
     ContextKey = "DataContext"; 
    } 
} 

की तरह एक विन्यास वर्ग बनाने के इस प्रकार तो निर्माता को बदलने:

public DataContext() 
{ 
    Database.SetInitializer(new MigrateDatabaseToLatestVersion<DataContext, DataContextConfiguration>()); 
} 

और आपका काम हो गया। प्लगइन से इकाई प्रकारों के लिए डेटाबेस टेबल स्वचालित रूप से तदनुसार बनाए/अपडेट किए जाएंगे।

संक्षेप में, यह स्वचालित रूप से स्वचालित माइग्रेशन सक्षम के साथ एक मानक कोड पहला दृष्टिकोण है, लेकिन गतिशील इकाई प्रकार पंजीकरण/कॉन्फ़िगरेशन OnModelCreating ओवरराइड के अंदर से है।

सीमाएं:

  • आप AutomaticMigrationDataLossAllowed = true निर्धारित नहीं करते हैं, जब मौजूदा प्लगइन निकाल दिया जाता है, एफई अपवाद है क्योंकि यह इसी टेबल को हटाने के लिए अनुमति नहीं है उत्पन्न होगा। और यदि आप ऐसा करते हैं, तो प्लगइन टेबल हटा दिए जाएंगे, इसलिए यदि प्लगइन दोबारा जोड़ा जाता है, तो यह शून्य से शुरू होगा।

  • प्लगइन इकाइयां केवल डेटा एनोटेशन का उपयोग करके कॉन्फ़िगर किया जा सकता है। यदि आप उन्हें पूर्ण नियंत्रण देना चाहते हैं, तो आपको शायद कुछ विधि कॉल करने के लिए प्लगइन इंटरफ़ेस बदलने और इकाई प्रकारों को लेने की बजाय, DbModelBuilder को पास करने की आवश्यकता होगी, ताकि वे अपने इकाई प्रकारों को स्वयं कॉन्फ़िगर करने के लिए फ़्लुएंट एपीआई का उपयोग कर सकें।

+0

धन्यवाद !!! यह काम कर रहा है! केवल एक प्रश्न: मैं नहीं चाहता कि अगर प्लगइन हटा दिया गया है तो ef टेबल को हटा रहा है! क्या आपको इसका कोई विचार है? – Flo

+1

जैसा कि मैंने उल्लेख किया है यह एक मुद्दा है। यदि आप इकाई प्रकार पंजीकृत नहीं करते हैं, तो EF मानता है कि यह हटा दिया गया है। यदि आप उपर्युक्त विकल्प सेट नहीं करते हैं (जो डिफ़ॉल्ट रूप से 'गलत' है), तो आपको अपवाद मिलता है। दुर्भाग्यवश AFAIK में कोई विकल्प नहीं है जो आपको मौजूदा टेबल छोड़ने की अनुमति देता है। तो आप सब कुछ या कुछ नहीं मिलता :( –

+0

ठीक है बहुत बहुत धन्यवाद! – Flo

0

मुझे नहीं लगता कि यह है कि यह होगा इस दृष्टिकोण का उपयोग करके कभी भी ईएफ 6 के साथ काम करें।

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

Update-Database –Verbose 

अगर यह विफल रहता है, के रूप में संदेशों पेस्ट करें:
इसके अलावा का उपयोग कर अपने अभी बनाया DatabaseContext सरल होना चाहिए

1

रन (आप सब कुछ मानक DbContext इंटरफ़ेस के माध्यम से अपनी कक्षा में पहुँचने के ऐसा करने में सक्षम होना चाहिए) एक टिप्पणी।

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