如何在RavenDB中将引用类型用作文档中的键

如何在RavenDB中将引用类型用作文档中的键,ravendb,composite-key,Ravendb,Composite Key,我有一个类,我想用于文档密钥: 我还实现了ITypeConverter(不是.NET接口,特定于RavenDB的接口)来将引用类型转换为字符串(因为在数据库中,) 最后,我通过通过约定.IdentityProviders属性公开的列表将itypecoverter的实现添加到IDocumentStore实现中 但是,IAsyncDocumentSession实现上的LoadAsync重载上的签名如下所示(为了简洁起见,删除了使用多个ID的签名。另外,与IDocumentSession接口上的Loa

我有一个类,我想用于文档密钥:

我还实现了
ITypeConverter
(不是.NET接口,特定于RavenDB的接口)来将引用类型转换为字符串(因为在数据库中,)

最后,我通过通过
约定.IdentityProviders
属性公开的
列表
itypecoverter
的实现添加到
IDocumentStore
实现中

但是,
IAsyncDocumentSession
实现上的
LoadAsync
重载上的签名如下所示(为了简洁起见,删除了使用多个ID的签名。另外,与
IDocumentSession
接口上的
Load
相同):

LoadAsync(字符串id);
LoadAsync(ValueType id);
由于以下原因,我确实不想对键使用值类型:

  • 我有一个对键类型没有约束的抽象。创建单独的结构来反映这一点,只是为了拥有值类型,这是非常不方便的
  • 我无法通过限制为值类型来完全控制该类型。值类型有一个默认构造函数,它以一种我不想在代码的其他地方处理的方式默认值

如何使用引用类型作为RavenDB中的文档键?

因为所有文档标识符最终都存储为RavenDB中的字符串,所以该键使用了带字符串的重载:

LoadAsync<T>(string id);
以下是参数的作用:

  • id
    -这是用作文档标识符的对象。在上面的示例中,它将是
    DocumentKey
    实例。由于该类型为
    对象
    (而非对象),因此此处将接受引用类型
  • type
    -表示
    id
    所属项目类型的实例。调用
    LoadAsync
    时,这是
    typeof(T)
  • allowNull
    -这是作为
    allowNull
    参数在
    itypecoverter.ConvertFrom
    的实现中传递的,该参数添加到通过
    约定公开的
    IdentityProviders
这些都可以封装在强类型的
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);
}
static Task LoadAsync(此IAsyncDocumentSession会话,TId id)
{
//验证参数。
如果(session==null)抛出新的ArgumentNullException(“session”);
//检查id是否为空。
如果((object)id==null)抛出新的ArgumentNullException(“id”);
//获取字符串id。
string stringId=session.Advanced.DocumentStore.Conventions。
FindFullDocumentKeyFromNonSringIdentifier(id,typeof(T),true);
//使用字符串id加载。
返回session.LoadAsync(stringId);
}

LoadAsync<T>(string id);
string FindFullDocumentKeyFromNonStringIdentifier(
    object id, Type type, bool allowNull);
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);
}