Couchbase Lite resultset to object in C#?

.net

#1

Hi

I have this code to query my local CBLite database:

            var list = new List<Catch>();
            // SELECT * from data where type='Catch' limit 10
            using (var query = QueryBuilder.Select(
                    SelectResult.All())
                   .From(DataSource.Database(dataStore.Db))
                   .Where(Expression.Property("type").EqualTo(Expression.String("Catch")))
                   .OrderBy(Ordering.Property("date").Descending())
                   .Limit(Expression.Int(limit)))
            {
                var t = true;
                var result = query.Execute();
                foreach (var record in result.AllResults())
                {
                    var data = record.GetDictionary(dataStore.Db.Name);
                    if(t) Console.WriteLine(data.ToString());
                    t = false;
                    Console.WriteLine($"{data.GetString("type")}: {data.GetInt("count")}");
                    list.Add(JsonConvert.DeserializeObject<Catch>(data.ToString()));
                }
            }

The last line fails. Is there a way to get the JSON representation of a resultset (just the individual records/nodes)?

If not, then what is the best way to map these into my class to work with in the code?

Or shouldn’t I use a class - and then what would be the best way to work with data?

I’m on Couchbase Lite version 2.1.2 :slight_smile:


#2

No. (It’s never actually stored as JSON.)

There’s no special sauce to help you convert the results into custom objects, at least not yet. You’ll need to look at the named properties in the query row and set the properties of your object accordingly.


#3

Hmmm… Ok.

That’s a pitty. I had hoped that was a lot easier.

Well, nothing I can do about that now - but coding a lot more :face_with_raised_eyebrow:

Thanks for responding though.


#4

Ok , I thought I would just show how I have accomplished this - so if others search for it then you may be able to use the same approach…

First, I spent the day working with reflection - identifying datatypes, arrays, classes inside my class etc. etc. - quite tedious.

The problem really was that I could not get a JSON representation of my data from the database. So at some point I got my hands on an ordinary Dictionary<string,object> as opposed to the Couchbase LIte DictonaryObject as that was the only way I could find to use the same code for deserializing a JsonDocument and a Dictionary from a query resultset.

And then at a point the idea came to see if I could serialize/deserialize an ordinary Dictionary - and yes you can! Therefore, I replaced my relatively complex code with this:

private T deserialize(Dictionary<string, object> data)
{
   var json = JsonConvert.SerializeObject(data, Formatting.Indented);
   return JsonConvert.DeserializeObject<T>(json);
}

Voilá!

And this method I can call from traversing the query result set:

var result = query.Execute();
foreach (var record in result.AllResults())
{
    var data = record.GetDictionary(dataStore.Db.Name);
    list.Add(deserialize(data.ToDictionary()));
}

as well as from a document found directly by id:

var record = dataStore.Db.GetDocument(id);
var obj = deserialize(record.ToDictionary());

There may be better ways to do this (y0u could share your solution/comments here) - and really it should be part of the SDK.

I’ll mark this as a solution to make it easier for others to find :slight_smile:


#5

I’m glad you found a solution! It seems like a roundabout way of doing it, though – I’m sure the first thing JsonConvert.DeserializeObject does is parse the JSON back into objects. Maybe there’s an alternate method of JsonConvert that takes a Dictionary directly?

(Apologies if I’m being an idiot. I know nothing about .NET.)


#6

Hi jens

Not a bad idea - but I have not been able to find an exposed method to do that. Although it seems like an extra step - this is far better than trying to do it all by yourself…

But it would be nice to have some built-in (and optimised) functionality in CB Lite to help with this. Some sort of ORM or easy way to turn the data into objects - and possibly some documentation on best practice :innocent:

/John


#7

Definitely, and I’ve been a big advocate of this. Couchbase Lite 1.x had this functionality for Objective-C and Swift, but not other languages. In the move to 2.0 we focused on keeping our API the same across platforms, which unfortunately meant that intrinsically platform-specific features like this got pushed aside. We do want to add it in the future but it’s not scheduled yet.

(Note that this could be implemented as a 3rd party library since it doesn’t require access to the innards of Couchbase Lite…)


#8

Thanks for your insight @jens,

On the API across languages I have actually posted another question that has so far attracted no attention: Considerations about dates and attachments

The dates have been “solved” by using the above JSON serialize/deserialize. However, the blobs are still interesting as it seems a little too heavy to have to base64 encode/decode all the time :slight_smile: