2013-02-21 76 views
0

我試圖通過CascadeDelete RavenDB軟件包嵌入RavenDB,但該軟件包似乎沒有被激活,在這個應用程序中實現級聯刪除。我應該怎麼做呢?如何集成嵌入式RavenDB和CascadeDelete包?

在下面的代碼片段是一個測試控制檯應用程序,試圖在嵌入式/內存RavenDB數據庫中啓用級聯刪除,我已經安裝了NuGet包RavenDB.Embedded 2.5.2505-Unstable和RavenDB.Bundles.CascadeDelete 2.5 0.2505不穩定吧:

using System; 
using System.Linq; 
using Raven.Client; 
using Raven.Client.Embedded; 
using Raven.Json.Linq; 

namespace ConsoleApplication1 
{ 
    public class Parent 
    { 
     public string Id { get; set; } 
    } 

    public class Child 
    { 
     public string Id { get; set; } 
     public string ParentId { get; set; } 
    } 

    public static class RavenExtensions 
    { 
     public static void AddCascadeDeleteReference(this IAdvancedDocumentSessionOperations session, 
      object entity, params string[] documentKeys) 
     { 
      var metadata = session.GetMetadataFor(entity); 
      if (metadata == null) 
       throw new InvalidOperationException(
        "The entity must be tracked in the session before calling this method."); 

      if (documentKeys.Length == 0) 
       throw new ArgumentException(
        "At least one document key must be specified."); 

      const string metadataKey = "Raven-Cascade-Delete-Documents"; 

      RavenJToken token; 
      if (!metadata.TryGetValue(metadataKey, out token)) 
       token = new RavenJArray(); 

      var list = (RavenJArray)token; 
      foreach (var documentKey in documentKeys.Where(key => !list.Contains(key))) 
       list.Add(documentKey); 

      metadata[metadataKey] = list; 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      var store = new EmbeddableDocumentStore { RunInMemory = true }; 
      store.Initialize(); 
      Parent parent; 
      using (var session = store.OpenSession()) 
      { 
       parent = new Parent(); 
       session.Store(parent); 
       session.SaveChanges(); 

       var child = new Child(); 
       child.ParentId = parent.Id; 
       session.Store(child); 
       session.Advanced.AddCascadeDeleteReference(parent, child.Id); 
       session.SaveChanges(); 
      } 

      using (var session = store.OpenSession()) 
      { 
       Console.WriteLine("Before deleting parent:"); 
       foreach (var child in session.Query<Child>()) 
       { 
        Console.WriteLine(" Child: {0} of parent {1}", child.Id, child.ParentId); 
       } 

       parent = session.Load<Parent>(parent.Id); 
       session.Delete(parent); 
       session.SaveChanges(); 

       Console.WriteLine("After deleting parent:"); 
       foreach (var child in session.Query<Child>()) 
       { 
        Console.WriteLine(" Child: {0} of parent {1}", child.Id, child.ParentId); 
       } 

       Console.WriteLine("Press any key..."); 
       Console.ReadKey(); 
      } 
     } 
    } 
} 

當你運行這個程序,你應該看到的是,孩子是不是與父刪除,即使它被配置爲通過級聯刪除。請指出我怎樣才能使級聯刪除這個程序:)工作

更新:

我試着加入以下後store.Initialize();,但它並沒有區別:

store.DocumentDatabase.Configuration.Catalog.Catalogs.Add(
      new AssemblyCatalog(typeof(CascadeDeleteTrigger).Assembly)); 

回答

0

這有點違反直覺,但我發現我需要將packages\RavenDB.Bundles.CascadeDelete.2.5.2505-Unstable\lib\net40\Raven.Bundles.CascadeDelete.dll複製到ConsoleApplication1\Plugins\Raven.Bundles.CascadeDelete.dll並將Visual Studio配置爲將文件複製到輸出目錄,以供RavenDB選取。

現在,CascadeDelete包工作,並且該子包與父包一起被刪除。

enter image description here

+0

如果您想避免這種情況,請參閱我的答案中的選項#2。 – 2013-02-21 14:45:31

2

既然你在嵌入模式,你有兩個選擇:

  1. 可以捆綁的dll複製到插件目錄。

  2. 您可以參考束DLL,然後將其添加到手動的目錄:

    documentStore.DocumentDatabase.Configuration.Catalog.Catalogs 
        .Add(new AssemblyCatalog(typeof(CascadeDeleteTrigger).Assembly)); 
    

不要兩者都做不過。如果你使用選項#2,那麼捆綁DLL應該不在插件文件夾中,否則它會被拾取兩次。

+0

你的選擇#2看起來不錯,但我不能讓它工作。我甚至試圖把它與選項#1結合起來看看它是否至少會引起衝突,但是它只是起作用,就好像我只實現了選項#1一樣。你能修改我的測試程序來使用選項#2,驗證它是否有效,併發布代碼? – aknuds1 2013-02-21 17:07:50

+0

@ aknuds1 - 我一直都在使用這種方法。它應該只是工作。確保你正在使用你正在運行的RavenDB相同版本的級聯刪除包dll。請注意,對於命名包,您還需要修改'Raven/ActiveBundles'設置,但級聯刪除包未命名。 (它不會在其元數據中導出「Bundle」名稱)。所以一旦連線就會被激活。 – 2013-02-22 15:56:53

+0

嗯,我只能再次敦促你請張貼一個工作示例,因爲我無法弄清楚我做錯了什麼。就像我說的,選項#1完美地工作,而向目錄添加捆綁軟件什麼也不做(它也被引用)。 – aknuds1 2013-02-22 18:25:14