2012-06-27 12 views
11

Trong cơ sở dữ liệu, tôi đã lưu trữ hàng trăm tài liệu. Bây giờ kiến ​​trúc hệ thống đã thay đổi và (trong số những người khác) mô hình đã được di chuyển vào không gian tên khác nhau (trong lắp ráp khác nhau).RavenDB ném ngoại lệ sau khi thay đổi không gian tên mô hình

Dưới đây, siêu dữ liệu của tài liệu mẫu được hiển thị:

enter image description here

và mã Tôi đang sử dụng để lấy tài liệu ví dụ:

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

mà ném đúc ngoại lệ:

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

CẬP NHẬT:

Lỗi tương tự nhưng từ NewtonsoftJson tăng lên, trong khi tôi có bộ sưu tập loại được chỉ định bên trong dosument, hiện đã thay đổi.

Trong cơ sở dữ liệu tôi có Câu hỏi tài liệu, trong đó có chứa một danh sách các trả lời:

enter image description here

Trong mã, kiểu trông như thế:

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; }   
    } 
} 

Đáp namespace thay đổi. Ngoài ra, bây giờ nó bắt nguồn từ IList <>, không có ICollection <>. Hiện tại, tôi không cần siêu dữ liệu $type, phải là:

enter image description here.

Trong khi đó là một danh sách bây giờ, một lỗi tăng vì những thông tin cũ $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'. 

cách tốt nhất để di chuyển tất cả các tài liệu để phản ánh các loại tên hiện nay là gì? Có cơ chế tích hợp nào không?

Btw: Tôi đang sử dụng RavenDB - Xây dựng # 960

Trả lời

3

Jarek, Lý do cho vấn đề là bạn CÓ cả hai loại. Nếu bạn loại bỏ loại QA, nó sẽ chỉ hoạt động. Hoặc, bạn có thể làm như Wyatt gợi ý và ép buộc điều này.

+0

Cảm ơn, thực sự tôi đã có loại thứ hai. Sau khi xóa quạ đã tự động thay đổi thông tin meta tài liệu thành kiểu hiện tại "Raven-Clr-Type": "One.Social.Ask.Web.Models.Setting, One.Social.Ask.Web". Bạn có thể xem xét cập nhật câu hỏi của tôi không? Tôi có một vấn đề tương tự. – jwaliszko

+0

Điều này là chính xác. Giải quyết vấn đề của tôi :) Cảm ơn bạn Ayende –

+0

Tôi đã có cùng một vấn đề mà tôi thậm chí không thể xóa các tài liệu từ RavenDB Studio. Điều này là do clr-type cũ vẫn còn hiện diện trong một plugin! Tôi đã phải dừng lại ravendb, xóa các plugin, khởi động lại ravendb, xóa tất cả các tài liệu thông qua các studio (nó làm việc bây giờ), sau đó dừng lại ravendb một lần nữa, reïnstall các plugin và bắt đầu ravendb một lần nữa. – ldx

1

Bạn sẽ cần phải vá các tài liệu ravendb trực tiếp mà không cần cố gắng deserialize họ. Tôi đã không bao giờ phải làm điều này bản thân mình, nhưng tôi nghĩ rằng ma thuật được thực hiện bằng cách sử dụng các phương pháp được tìm thấy trong IDocumentSession.Advanced.DatabaseCommands, đặc biệt là Patch method.

tôi không thực sự có bất cứ điều gì để kiểm tra chống lại, nhưng tôi nghĩ rằng mã sẽ giống như thế:

//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 

Ngoài ra còn có một cách để làm điều này mà không cần vòng lặp thông qua bộ sưu tập nhưng tôi không chắc chắn làm thế nào để có hiệu lực đúng cách.

+1

để làm điều đó mà không lặp qua tất cả các tài liệu, bạn có thể sử dụng các hoạt động thiết lập dựa trên, xem http://ravendb.net/docs/client-api/set-based- hoạt động –

+1

Cảm ơn Matt, không chắc chắn nếu những người làm việc nếu bạn đang monkeying về với siêu dữ liệu mặc dù. –

+0

Cảm ơn lời khuyên. Điều gì sẽ xảy ra nếu tôi có một bộ sưu tập của một số loại bên trong tài liệu, và thay đổi không gian tên loại bộ sưu tập? (xem phần cập nhật) – jwaliszko

3

tôi đã cùng một vấn đề và kết thúc làm điều này:

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

tôi phải đối mặt với cùng một vấn đề chính xác của casting exception sau một đổi tên. Như đã đề cập trong các câu trả lời trước, tôi đã kết thúc việc vá tất cả tài liệu của mình dựa trên this snippet.

Chúng tôi cần cập nhật hai trường: Raven-Entity-NameRaven-Clr-Type.

Ví dụ

Đổi tên MyType để MyNewType, cập nhật các namespace My.Namespace.MyType-My.New.Namespace.MyNewType.

Raven-Entity-Name cần phải được thay đổi từ MyTypes thành MyNewTypes. Tại sao số nhiều? Cách tiếp cận "Công ước về cấu hình", as explained here.

Raven-Clr-Type cần được cập nhật từ My.Namespace.MyType thành 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 } 
      ); 
     }