保存新的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@正在创建的额外属性?
正如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)
这样一来,库就可以更改值,同时在代码中阻止它。