RavenDB не будет заполнять Id-поле - PullRequest
2 голосов
/ 20 августа 2011

Я новичок в NoSql и играю с (встроенным) RavenDb в F #.Проблема заключается в следующем: когда я запрашиваю запись из хранилища, она не заполняет поле 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 &lt- storeName
        let store = documentStore.Initialize()
        store

    let createIn store data =
        useRavenSession (store, true) (fun session -&gt session.Store(data))

    let loadId (id : string) store : SimpleTestData =
        useRavenSession (store, false) (fun session -&gt session.Load(id))

    [&ltFact&gt]
    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», фактическое).Если я передам неправильный идентификатор, функция вернется (как и ожидалось) - все остальные поля верны

Как и спросила Айенде: вот скриншот класса данных в ObjectBrowser.Свойства доступны только для чтения: enter image description here

и более или менее совпадает с образцом на github

ОБНОВЛЕНИЕ 2:

измененокод для использования следующих объектов данных:

<code>
    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 доступно для записи, остальное точно так же, и да ... thisработает.НО это почти противоположность того, что я обычно хочу.Я хочу, чтобы Id-поле было доступно только для чтения, и, возможно, чтобы написать другие, а не иначе ...

Полагаю, в какой-то момент я должен открыть билет или что-то в RavenDB - что вы думаете, ребята?

1 Ответ

4 голосов
/ 24 августа 2011

У клиента RavenDb, похоже, есть проблема со свойствами, которые считываются только как идентификатор (я не до конца понимаю, почему, возможно, вы захотите поднять это как проблему в их списке рассылки). Однако обойти это легко. Просто измените поле 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()
...