2012-06-27 12 views
11

データベースには、すでに何百ものドキュメントが保存されています。今度は、システムアーキテクチャが変更され、(他のものの中でも)モデルが(異なるアセンブリ内の)異なる名前空間に移行されました。以下は モデルネームスペースの変更後にRavenDBがキャスト例外をスローする

は、サンプル文書のメタデータが示されています:

enter image description here

とコードを、私は、このような文書を取得するために使用しています:キャストスロー

var configuration = documentSession.Load<One.Social.Core.Entities.Setting>("Setting"); 

例外:

[InvalidCastException: Unable to cast object of type 'One.QA.Core.Entities.Setting' to type 'One.Social.Core.Entities.Setting'.] 

更新日:

私はdosntの中に指定された型のコレクションを持っていますが、シンプルなエラーですが、NewtonsoftJsonが起きました。データベースで

私は回答のリストが含まれている質問文書、持っている:コードで

enter image description here

を、種類は以下のようになります。

namespace One.Social.Ask.Web.Models 
{ 
    public class Question 
    {   
     public string Content { get; set; } 
     public IList<One.Social.Ask.Web.Models.Answer> Answers { get; set; }   
    } 
} 

回答の名前空間が変更されました。さらに、IList <>、ICollection <>から派生しました。私は今、$typeメタを必要としません。

enter image description hereです。

それが今のリストですが、エラーは、古い$type情報の上昇:

Newtonsoft.Json.JsonSerializationException: Error resolving type specified in JSON 'System.Collections.ObjectModel.Collection`1[[One.QA.Core.Entities.Answer, One.QA.Core]], mscorlib'. ---> Newtonsoft.Json.JsonSerializationException: Could not find type 'System.Collections.ObjectModel.Collection`1[[One.QA.Core.Entities.Answer, One.QA.Core]]' in assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. 

現在のタイプ名を反映するために、すべての文書を移行するための最良の方法は何ですか?組み込みのメカニズムはありますか?

ところで:私はRavenDBを使用しています - あなたはそれらをデシリアライズしようとせずに直接ravendb文書にパッチを適用する必要があります#960

答えて

3

Jarek、 問題の原因は、両方の種類があることです。 QAタイプを削除しても機能します。 また、ワイアットが提案して強制することもできます。

+0

ありがとう、確かに私は2番目のタイプがありました。削除後、ravenはドキュメントメタ情報を現在のタイプ "Raven-Clr-Type": "One.Social.Ask.Web.Models.Setting、One.Social.Ask.Web"に自動的に変更しました。あなたは私の質問の更新を見ることができますか?私は別の同様の問題があります。 – jwaliszko

+0

これは正しいです。私の問題を解決しました:) Ayendeありがとうございます –

+0

私はRavenDB Studioからドキュメントを削除することもできない同じ問題を抱えています。これは古いclr-typeがまだプラグインに存在していたためです!私はravendbを停止し、プラグインを削除し、ravendbを再起動し、スタジオ経由ですべての文書を削除してから、再度ravendbを停止してプラグインを再インストールし、再度ravendbを起動しなければなりません。 – ldx

1

を構築します。私はこれまでにこれを行う必要はありませんでしたが、IDocumentSession.Advanced.DatabaseCommandsにあるメソッド、特にPatch methodを使用して魔法が行われていると思います。

私は本当にに対してテストするために何かを持っていないが、私は、コードは次のようになりすべきだと思う:

//s is your document session 
var toUpdate = s.Advanced.DatabaseCommands.StartsWith("Setting", 0, 128); 
foreach (var d in toUpdate) 
{ 
    var p = new PatchRequest(); 
    p.AllPositions = true; 
    p.Type = PatchCommandType.Modify; 
    d.Metadata["Raven-Clr-Type"] = "MyNewType"; 
    p.Value = d.ToJson(); 
    s.Advanced.DatabaseCommands.Patch(d.Key, new []{p}); 
} 
// push forward and repeat for all items in collection 

もコレクションをループせずにこれを行う方法がありますが、私はよく分かりませんそれを適切に行う方法。

+1

、あなたがhttp://ravendb.net/docs/client-api/set-based-を参照し、セットベースの操作を使用することができます操作 –

+1

おかげでマット、もしあなたがメタデータを使って猿を振っているのであれば、それらが機能するかどうかは分かりません。 –

+0

チップをありがとう。ドキュメントの内部にある型のコレクションがあり、コレクション型の名前空間が変更された場合はどうなりますか? (更新を参照してください) – jwaliszko

3

私は同じ問題を抱えていたし、これをやってしまった:

Advanced.DatabaseCommands.UpdateByIndex(
    "Raven/DocumentsByEntityName", 
     new IndexQuery {Query = "Tag:Album"}, 
     new []{ new PatchRequest() { 
      Type = PatchCommandType.Modify, 
      Name = "@metadata", 
      Nested= new []{ 
       new PatchRequest{ 
        Name= "Raven-Clr-Type", 
        Type = PatchCommandType.Set, 
        Value = "Core.Model.Album, Core" }}}}, 
     false); 
0

私は名前を変更した後casting exceptionの正確な同じ問題に直面していました。 前回の回答でアドバイスされたように、this snippetに基づいてすべてのドキュメントをパッチしました。

Raven-Entity-NameRaven-Clr-Typeの2つのフィールドを更新する必要があります。

My.Namespace.MyTypeからMy.New.Namespace.MyNewTypeに名前空間を更新し、MyNewTypeMyTypeの名前を変更します。

Raven-Entity-NameMyTypesからMyNewTypesに変更する必要があります。複数の理由"コンベンションオーバーコンベンション"アプローチ、as explained here

Raven-Clr-Typeは、My.Namespace.MyTypeからMy.New.Namespace.MyNewTypeに更新する必要があります。すべてのドキュメントをループせずにそれを行うに

コード

public static void PatchMetadata() 
     { 
      var operation = session.Advanced.DocumentStore.DatabaseCommands 
      .UpdateByIndex(
       // You can check your index name in the Studio Under INDEXES. 
        "Raven/DocumentsByEntityName", 
       // query that will be performed 
        new IndexQuery 
        { 
         // A collection in RavenDB is a set of documents with the same tag. 
         // The tag is defined in Raven-Entity-Name. 
         Query = "Tag:MyTypes" 
        }, new[] 
           { 
            new PatchRequest 
             { 
              Type = PatchCommandType.Modify, 
              Name = "@metadata", 
              Nested = new[] 
               { 
                new PatchRequest 
                 { 
                  Type = PatchCommandType.Set, 
                  Name = "Raven-Entity-Name", 
                  Value = new RavenJValue("MyNewTypes") 
                 } 
                 , 
                new PatchRequest 
                 { 
                  Type = PatchCommandType.Set, 
                  Name = "Raven-Clr-Type", 
                  Value = new RavenJValue("My.New.Namespace.MyNewType, RavenDbPatching") 
                 } 
               } 
             } 
           }, 
        new BulkOperationOptions() { AllowStale = true } 
      ); 
     } 
関連する問題