2012-12-22 26 views
2

我有,我想在RavenDB使用爲一個文件鍵的一類:如何使用引用類型作爲關鍵文件在RavenDB

public class DocumentKey 
{ 
    public string Namespace { get; set; } 
    public string Id { get; set; } 
} 

我還實施了ITypeConverter(不.NET之一,RavenDB特定的一個)接口將參考類型轉換爲字符串(因爲在數據庫中,the keys are all really just strings)。

最後,我已將ITypeConverter的實現添加到IDocumentStore實現中,通過List<ITypeConverter>通過Conventions.IdentityProviders屬性公開。

然而,在IAsyncDocumentSession實施LoadAsync<T>重載簽名看起來像這樣(去除其中需要多個ID爲簡潔的簽名此外,同爲LoadIDocumentSession接口上。):

LoadAsync<T>(string id); 
LoadAsync<T>(ValueType id); 

我真的不想爲我的密鑰使用值類型,原因如下:

  • 我有一個抽象,它對鍵的類型沒有約束。創建單獨的結構來鏡像這只是具有值類型非常不方便
  • 由於被限制爲值類型,我無法完全控制該類型。值類型有一個默認構造函數,它以我不想在代碼中的其他任何地方處理的方式默認值。

如何在RavenDB中使用引用類型作爲文檔鍵?

回答

2

因爲所有文件標識符作爲RavenDB字符串存儲的最終存儲,關鍵是使用以一個字符串的過載:

LoadAsync<T>(string id); 

IAsyncDocumentSession接口,則可以使用Conventions(由Advanced.DocumentStore.Conventions曝光) ,特別是FindFullDocumentKeyFromNonStringIdentifier代表,它具有以下特徵:

string FindFullDocumentKeyFromNonStringIdentifier(
    object id, Type type, bool allowNull); 

下面是參數做:

  • id - 這是用作文檔標識符的對象。在上面的例子中,它將是DocumentKey實例。由於這是鍵入爲object(而不是ValueType),因此此處將接受引用類型。
  • type - 代表id所屬項目類型的Type實例。當致電LoadAsync<T>時,這是typeof(T)
  • allowNull - 這是作爲在ITypeConverter.ConvertFrom實施被添加到通過Conventions暴露IdentityProvidersallowNull參數傳遞。

這都可以在一個擴展方法包裹起來,在IAsyncDocumentSession(或修改IDocumentSession如果你想)是強類型的,像這樣:

static Task<T> LoadAsync<T, TId>(this IAsyncDocumentSession session, TId id) 
{ 
    // Validate parameters. 
    if (session == null) throw new ArgumentNullException("session"); 
    // Check if the id is null. 
    if ((object) id == null) throw new ArgumentNullException("id"); 

    // Get the string id. 
    string stringId = session.Advanced.DocumentStore.Conventions. 
     FindFullDocumentKeyFromNonStringIdentifier(id, typeof(T), true); 

    // Load using the string id. 
    return session.LoadAsync<T>(stringId); 
} 

Note that the if ((object) id == null) comparison can have a performance impact in this scenario.

相關問題