2017-02-17 7 views
1

So bin ich in der Situation, wo ich eines der Modelle in meiner Datenbank migrieren muss. Ich habe dem Modell ein -Feld hinzugefügt, das ein Datum für mein Recommendation-Modell enthält, das derzeit nicht in der Datenbank vorhanden ist. Es gibt also keine Möglichkeit, das neue Feld aus den vorhandenen Daten zu bestücken.Entfernen Sie Daten aus alten Realm während der Realm-Datenbankmigration

In meiner Migration Rückruf möchte ich ein unbeschriebenes Blatt für das Recommendation Modell und alle seine Untermodelle (es besteht aus ein paar Klassen). So kann ich einen neuen Datensatz mit Empfehlungen aus meiner Web-API mit dem neuen Feld holen. Wenn ich versuche, die alte Datenbank aller vorhandenen Modelldaten zu bereinigen, erhalte ich eine Ausnahme.

Realms.Exceptions.RealmInvalidTransactionException

ausführen können keine Transaktionen auf read-only Realms.

Wie erreiche ich das Obige?

Hier ist der relevante Code für meinen Migrationsrückruf.

 var config = new RealmConfiguration("salt.realm"); 
     config.SchemaVersion = 2; 
     config.MigrationCallback = (migration, oldSchemaVersion) => 
     { 
      Settings.UpdateDateRecommendationsUtc = DateTime.MinValue; 

      migration.OldRealm.Write(() => 
      { 
       migration.OldRealm.RemoveAll("RecDataString"); 
       migration.OldRealm.RemoveAll("RecChart"); 
       migration.OldRealm.RemoveAll("RecSummary"); 
       migration.OldRealm.RemoveAll("RecTickerSymbol"); 
       migration.OldRealm.RemoveAll("Recommendation"); 
      }); 
     }; 

Antwort

0

Da Sie nicht möchten, dass alle Daten für die fünf RealmObject s während der Migration beibehalten werden, RemoveAll vom NewRealm, da die Daten bereits mit entweder die Standardwerte für zusätzliche Objekte im NewRealm verfügbar sein oder fehlen Eigenschaften für diejenigen, die entfernt wurden.

Sie müssen nur die OldRealm Daten während der Migration, wenn Sie für den Zugriff auf „alte“ Eigenschaften benötigen und irgendeine Art von Datentransformation auf sie durchführen und die NewRealm damit aktualisieren ...

migration.NewRealm.RemoveAll<POCO>(); 
await UpdateRecommendationFromYourWebApi(); 

Hinweis: Da Sie fügen einen hinzu, möchten Sie vielleicht einen aktuellen Fehler zur Kenntnis nehmen, der den Standardwert auf "1/1/1970 12:00:00 AM + 00: 00" vs. "1/1/0001 12: 00.00 +00: 00"

Re: https://github.com/realm/realm-dotnet/issues/1225

+0

Hallo SushiHangover, du hast recht und fast richtig, ich habe herausgefunden, es wird eine aktualisierte Antwort posten. Benötigt nicht den NewRealm.Write() -Teil, da sich herausstellt, dass der MigrationCallback selbst eine Write-Transaktion ist. Außerdem mag es den Aufruf von RemoveAll ("") nicht. Es wird eine RealmException ausgelöst, die sich darüber beschwert, dass Realm.RemoveRange() ein IQueryable von .All oder ähnlichem erwartet. Ich denke, es verwendet Realm.RemoveRange() unter der Haube. Siehe meine aktualisierte Antwort. Danke auch für den heads-up auf dem DateTimeOffset Bug !!! –

+0

@MarkSilver Ich habe das aus dem Speicher und nur ausschneiden/fügen Sie Ihren Code ..., verwenden Sie 'migration.NewRealm.RemoveAll ();' anstelle von 'RemoveRange' – SushiHangover

+0

Ich habe es mit der' RemoveAll () 'getestet Typ Parameterfunktion und es funktioniert. Es scheint, es ist nur die dynamische Funktion, die es nicht mag 'RemoveAll (" className ")' wird eine Ausnahme auslösen. Danke für die Hilfe. –

0

Also wie @SushiHangover richtig sagte, hätte ich eher auf der newRealm als auf der altenRealm arbeiten sollen. Wie ich es besorgt habe, wurden die RealmObjects des neuen Realms entfernt. Keine Schreibtransaktion erforderlich, da config.MigrationCallback bereits eine Schreibtransaktion ist. Ich konnte nicht RemoveAll("className") zu arbeiten es löst eine Ausnahme, das ist die funktionierende Lösung, die ich derzeit habe.

 var config = new RealmConfiguration("salt.realm"); 
     config.SchemaVersion = 1; 
     config.MigrationCallback = (migration, oldSchemaVersion) => 
     { 
      Settings.UpdateDateRecommendationsUtc = DateTime.MinValue; 

      migration.NewRealm.RemoveAll<Recommendation>(); 
      migration.NewRealm.RemoveAll<RecDataString>(); 
      migration.NewRealm.RemoveAll<RecChart>(); 
      migration.NewRealm.RemoveAll<RecSummary>(); 
      migration.NewRealm.RemoveAll<RecTickerSymbol>(); 
     }; 
Verwandte Themen