我是NoSql的新手,正在F#中使用(嵌入式)RavenDb。 问题是:当我从商店查询记录时,它不会填写Id字段(为空) - 其余的都是正确的。
这是预期的行为吗?为什么?
这是带有问题的测试代码:
open Xunit
open System.Linq
module RavenDbPOC =
type SimpleTestData =
{
Id : string
Name : string
Value : int
}
let testId = "12345"
let testName = "MaxMustermann"
let testValue = 42
let createSampleData() = { Id = testId; Name = testName; Value = testValue }
let createRandomStoreName() =
let baseName = "ProofOfConceptData"
let id = System.Guid.NewGuid().ToString()
sprintf @"c:\temp\%s_%s" baseName id
let useRavenSession(store : Raven.Client.IDocumentStore, saveChanges : bool) doWorkWith =
use session = store.OpenSession()
let result = doWorkWith session
if saveChanges then session.SaveChanges()
result
let initializeDocumentStore() =
let storeName = createRandomStoreName()
let documentStore = new Raven.Client.Embedded.EmbeddableDocumentStore()
documentStore.DataDirectory <- storeName
let store = documentStore.Initialize()
store
let createIn store data =
useRavenSession (store, true) (fun session -> session.Store(data))
let loadId (id : string) store : SimpleTestData =
useRavenSession (store, false) (fun session -> session.Load(id))
[<Fact>]
let CanReadStoredData() =
use store = initializeDocumentStore()
createSampleData() |> createIn store
let data = store |> loadId testId
Assert.Equal(testId, data.Id)
Assert.Equal(testName, data.Name)
Assert.Equal(testValue, data.Value)
测试将抛出第一个断言(预期“12345”,实际)。 如果我传递错误的Id,函数将返回(如所示) - 所有其他字段都是正确的
正如Ayende所问:这是ObjectBrowser中数据类的屏幕截图。属性是只读的:
它与github
上的样本大致相同更新2:
更改了代码以使用以下数据对象:
type TestData(id : System.Guid, name : string, value : int) =
let mutable _id = id
member x.Id with get() = _id and set(id) = _id <- id
member x.Name with get() = name
member x.Value with get() = value
AFAIK唯一重要的区别在于,现在Id属性是可写的,只是相同而且是的......这是有效的。 但它几乎与我正常想要的相反。我希望Id字段是只读的,也许是以其他方式写出其他字段......
我想这是我应该用RavenDB打开一张票或什么的 - 你们觉得怎么样?
答案 0 :(得分:4)
RavenDb客户端似乎存在一个问题,即只读作为id的属性(我不完全理解为什么会这样,你可能想把它作为一个问题在他们的邮件列表中提出)。但是,解决方法很容易。只需将id字段更改为mutable,然后一切都将按预期工作。这只是一个做出以下改变的案例:
type SimpleTestData =
{
mutable Id : string
Name : string
Value : int
}
通常最好将id设置为null以允许ravendb生成id:
let createSampleData() = { Id = null; Name = testName; Value = testValue }
最后,使用记录时的一个问题是ravendb客户端在其缓存中存储加载类型的副本并尝试跟踪更改。如果您尝试复制记录并重新保存,则此方法不能很好地工作。为了解决这个问题,您需要逐出以前存储的类型:
let myRecord = session.Load("simpletestdata/123")
let myRecord' = { myRecord with Value = 52 }
session.Advanced.Evict myRecord
session.Store myRecord'
session.SaveChanges()