我有一个类要用于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
的实施。
但是,LoadAsync<T>
实施的IAsyncDocumentSession
重载上的签名如下所示(为了简洁起见,删除了带有多个ID的签名。此外,与Load
上的IDocumentSession
相同{1}}界面):
LoadAsync<T>(string id);
LoadAsync<T>(ValueType id);
我真的不想为我的密钥使用值类型,原因如下:
如何在RavenDB中使用引用类型作为文档密钥?
答案 0 :(得分: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
- 这是作为allowNull
实施中的ITypeConverter.ConvertFrom
参数传递的,该IdentityProviders
参数已添加到通过Conventions
公开的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);
}
)强类型,如下所示:
{{1}}
Note that the if ((object) id == null)
comparison can have a performance impact in this scenario.