用F#在RavenDb中保存记录以添加额外的ID列

Max*_*Max 1 f# ravendb

保存新的F#记录时,我Id@在RavenDb文档中获得了一个额外的列,当我在代码中加载或查看该对象时会显示该列;它甚至可以通过我的F#API转换为JSON。

这是我的F#记录类型:

type Campaign = { mutable Id : string; name : string; description : string }
Run Code Online (Sandbox Code Playgroud)

我没有做任何令人兴奋的事情来保存它:

let save c : Campaign =
    use session = store.OpenSession()
    session.Store(c)
    session.SaveChanges()
    c
Run Code Online (Sandbox Code Playgroud)

保存记录的新实例将创建ID为的文档campaigns/289。这是RavenDb中文档的全部价值:

{
    "Id@": "campaigns/289",
    "name": "Recreating Id bug",
    "description": "Hello StackOverflow!"
}
Run Code Online (Sandbox Code Playgroud)

现在,当我在C#中使用相同的数据库(和文档)时,我没有获得额外的Id@价值。这是我在C#中保存记录时的样子:

{
    "Description": "Hello StackOverflow!",
    "Name": "Look this worked fine",
}
Run Code Online (Sandbox Code Playgroud)

(此外-“名称”与“名称”表示我的文档中有2个名称列。至少我理解该问题)。

所以我的问题是:在RavenDb中保存F#记录时,如何摆脱Id@正在创建的额外属性?

N_A*_*N_A 5

正如Fyodor所指出的,这是由创建记录类型时F#如何生成后备字段引起的。RavenDB的默认合同解析器会序列化该后备字段,而不是公共属性。

您可以在ravendb中更改默认合同解析器。 如果要使用Newtonsoft Json.Net,它将看起来像这样:

DocumentStore.Conventions.JsonContractResolver <- new CamelCasePropertyNamesContractResolver()
Run Code Online (Sandbox Code Playgroud)

还有为什么这个工程的说明这里(请参见标题为:“解释”)。简而言之,Newtonsoft库使用该类型的公共属性而不是私有后备字段。

我还建议,不要将mutable属性放在上,而Id可以将[<CLIMutable>]属性放在类型本身上,例如:

[<CLIMutable>]
type Campaign = { Id : string; name : string; description : string }
Run Code Online (Sandbox Code Playgroud)

这样一来,库就可以更改值,同时在代码中阻止它。