Retrieving values from record

I am back to work my proof of concept WinForms app to move our small Access db to Couchbase. Thanks to the Couchbase community I’m happily adding records. That’s fine, but now I need to retrieve the information in the database and populate the fields on our form.

A single document contains this information:

{{
  "arctic-tweed-sample": {
    "barCode": "895746",
    "isPhysicalAsset": true,
    "manufacturer": "Astare Instruments",
    "itemName": "Lumalace",
    "itemPartNumber": "HES-SF-012",
    "itemSerialNumber": "78456565",
    "location": "Plant 1",
    "section": "Warehouse",
    "rack": "W",
    "shelf": "0",
    "bin": "",
    "equipmentCategory": "Lighting",
    "tags": [
      "Astare",
      "750 watt",
      "flood",
      "led"
    ]
  }
}}

And created a class for my record object

    public class KElement
    {
        public string Key { get; set; }
        public string Type { get; set; }
        public string BarCode { get; set; }
        public string ItemName { get; set; }
        public string ItemPartNumber { get; set; }
        public string ItemSerialNumber { get; set; }
        public bool IsPhysicalAsset { get; set; }
        public string Location { get; set; }
        public string Section { get; set; }
        public string Rack { get; set; }
        public string Shelf { get; set; }
        public string Bin { get; set; }
        public string Manufacturer { get; set; }
        public string EquipmentCategory { get; set; }
        public string SalesCategory { get; set; }
        public List<string> Tags { get; set; }
        public List<string> RequiredAccessories { get; set; }
    }

I can successfully return the document from the bucket using the method:

private async void btnGetRecord_Click(object sender, EventArgs e)
    {
        var cluster = await Cluster.ConnectAsync("http://xxx.xx.xx.xxx", "myTestUser", "myTestUserPassword");
        var bucket = await cluster.BucketAsync("arctic-tweed-sample");
        var queryResult = await cluster.QueryAsync<dynamic>(@"SELECT * FROM `arctic-tweed-sample` USE KEYS '2020123168109970'");
        // test various methods to retrieve key-values from document
        await cluster.DisposeAsync();
    }

To retrieve the keys and values in my document I’ve used methods like

     var record = await queryResult.ToListArrayAsync();

I know my KVs are there because I can view them in debug … record > Non-Public member > _result > [0]

I tried casting record to my KElement class but receive the error … cannot implicitly cast convert type System.Collections.Generic.List to target type Mynamespace.KElement

I also attempted to use

        var queryResult = await cluster.QueryAsync<List<KElement>>(@"SELECT * FROM `arctic-tweed-sample` USE KEYS '2020123168109970'");

and got the error … Cannot deserialize the current JSON object (e.g. {“name”:“value”}) into type System.Collections.Generic.List`[Enkadia.Alloy.WinForms.KElement] because the type requires a JSON array

I trying to think of other ways to get to my values, but am coming up empty.
Thanks for any help.
Norm

Hi @normschaeffer -

Good to hear! You just need to change your query to something like:

"SELECT s.* FROM `arctic-tweed-sample` as s USE KEYS '2020123168109970'"

The reason is that N1QL will add the bucket name as the root element to the JSON results returned from the Query engine. By adding the alias, this root element will be removed.

Also:

  • If your doing a single key lookup, you’ll get better performance if you use the K/V API: await bucket.DefaultCollection().GetAsync(key);

  • I see you are scoping the bucket and cluster to a method, this is an anti-pattern. Your better off scoping both to the application level. This is so that the socket connections and other resources can be reused over and over without incurring the overhead cost of creating them every time.

-Jeff

1 Like