1

我正在尝试利用 RavenDB 的 DocumentConvention API 在我的域对象上自动设置增量 ID。

我在 IDocumentStore 上使用这行代码完美地工作:

DocumentStore.Conventions.RegisterIdConvention<User>
    ((dbname, commands, user) => "users/" + commands.NextIdentityFor("users"));

每当我存储一个未设置 ID 的新用户对象时,这都会创建我的用户对象的顺序 ID,其中包含"users/1""users/2"等。

但是,我想为异步文档会话执行此操作,但在调用RegisterAsyncIdConvention()时无法找到有关如何从会话中获取“下一个身份”的任何文档...

docStore.Conventions.RegisterAsyncIdConvention<User>
    ((dbname, commands, user) => "users/" + commands.NextIdentityFor("users"));

... 无法编译,因为NextIdentityForIAsyncDatabaseCommands接口上不可用。

任何人都可以给我任何提示吗?有没有人尝试过这样做?

谢谢。

4

1 回答 1

5

您使用顺序 ID 描述的行为已经是默认行为。您无需对约定进行任何特殊操作即可获得此行为。

它也适用于异步会话 - 但最初它在第一次存储时实际上并没有设置 id 属性的值。这在此线程的邮件列表中进行了讨论。我相信拉取请求使它成为最新的不稳定版本,但我尚未验证。

更新 (来自评论)

默认情况下,约定是使用类型名称的复数形式。如果类型名称是单个单词,则以小写形式返回。如果它有多个单词,则保留大小写。

考虑:

var user = new User { Name = "Joe" };
session.Store(user);

var fooBar = new FooBar { Name = "Whatever" };
session.Store(fooBar);

Debug.WriteLine(user.Id);
Debug.WriteLine(fooBar.Id);

在不更改约定的情况下,这将输出:

users/1
FooBars/1

如果你想改变这个约定,你只需提供一个新的 lambda 函数:

documentStore.Conventions.FindTypeTagName = type => type.Name.ToLower();

运行与之前相同的代码,您现在将获得:

user/1
foobar/1

但也许你想保持复数形式,只想要全部小写?

documentStore.Conventions.FindTypeTagName = type =>
              DocumentConvention.DefaultTypeTagName(type).ToLower();

输出:

users/1
foobars/1

也许你总是想要 PascalCase?

documentStore.Conventions.FindTypeTagName = type =>
{
    var s = DocumentConvention.DefaultTypeTagName(type);
    return s.Substring(0, 1).ToUpper() + s.Substring(1);
};

输出:

Users/1
FooBars/1

或者也许总是camelCase?

documentStore.Conventions.FindTypeTagName = type =>
{
    var s = DocumentConvention.DefaultTypeTagName(type);
    return s.Substring(0, 1).ToLower() + s.Substring(1);
};

输出:

users/1
fooBars/1
于 2013-03-18T21:06:50.823 回答