2012-06-27 51 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'.] 

更新:

類似的錯誤,但來自NewtonsoftJson上升,而我已收集指定的類型,現在改變dosrar。

在數據庫中,我有問題的文件,其中包含答案的列表:

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 meta,它應該是:

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 - 建立#960

回答

3

Jarek, 問題的原因是你有兩種類型。 如果您刪除QA類型,它將會正常工作。 或者,您可以按照Wyatt的建議並強制執行此操作。

+0

謝謝,的確我有第二種類型。刪除烏鴉已自動將文檔元信息更改爲當前類型「Raven-Clr-Type」:「One.Social.Ask.Web.Models.Setting,One.Social.Ask.Web」。你能看看我的問題的更新嗎?我有另一個類似的問題。 – jwaliszko

+0

這是正確的。解決了我的問題:)謝謝Ayende –

+0

我有同樣的問題,我甚至無法從RavenDB Studio中刪除文檔。這是因爲舊的clr類型仍然存在於插件中!我不得不停止ravendb,刪除插件,重新啓動ravendb,通過工作室刪除所有文件(現在工作),然後再次停止ravendb,重新安裝插件並再次啓動ravendb。 – ldx

1

你需要直接修補ravendb文檔,而不試圖反序列化他們。我自己從來沒有這樣做過,但我認爲使用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

感謝馬特,不知道如果這些工作,如果你是與元數據monkeying雖然。 –

+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

重命名MyTypeMyNewType,更新命名空間從My.Namespace.MyTypeMy.New.Namespace.MyNewType

Raven-Entity-Name需要從MyTypes更改爲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 } 
      ); 
     } 
相關問題