Couchbase Lite 2.0, From Db19 to Db21, Xamarin .net c#

Hi,

I’m trying to jump from the DB19 version to the db 21, in my Xamrin c# project, using couchbase lite 2.0.

to be able to save my documents correctly, I coded this methode :

private static void DicoToDocument(Document document, IDictionaryObject dico)
	{
		foreach (string key in dico.Keys)
		{
			string typeOfObject = dico.GetObject(key).GetType().ToString();
			switch(typeOfObject)
			{
				case "System.Int64": document.Set(key, dico.GetLong(key)); break;
				case "System.Int32": document.Set(key, dico.GetInt(key));break;
				case "Couchbase.Lite.IDictionaryObject": 
				case "Couchbase.Lite.DictionaryObject": document.Set(key, dico.GetDictionary(key)); break;
				case "System.String": document.Set(key, dico.GetString(key)); break;
				case "System.DateTime": document.Set(key, dico.GetDate(key)); break;
				case "Couchbase.Lite.ArrayObject": document.Set(key, dico.GetObject(key)); break;
				default:
					Debugger.Break();
					document.Set(key, dico.GetObject(key));
					break;
			}
		}
	}

And I’m calling it like that :

Document document = new Document(docId); // db19
		IDictionaryObject dico = aSauver.DocumentInitialize();
		DicoToDocument(document, dico);
		_dataBase.Save(document);

I just changed my NuGet package version to db21, applied the documentated changes for the db20 version, and realised that the class IDictionaryObject don’t have the GetObject(key) methode anymore. As shown upper, I’m using it to obtain the type of the stored object.
So I’have 2 questions :

  • How can I do to obtain the type of the stored object since the db21 version ?

  • I’m not quite sure i’m using the proper way to store my objects in documents. It’s more simple with the couchbase Netclient librery, I just have to do so :

     		communes.ForEach(commune =>
     	{
     		Document<Commune> document = new Document<Commune>();
     		document.Content = commune.ToCommune();
     		document.Id = $"commune_{commune.Num}";
     		_couchbaseConnector.BucketGiver().Insert(document);
     	});
    

I don’t have to play with the dictionnary. Is teire an equivalente way to do so in couchbase Lite ?

Thank you

Steeve

GetObject was renamed to GetValue.

As far as the .NET SDK client, that is a featured that we call data modeling that we plan to release in a future version of the mobile library. So for now, the way you are doing it is the only way.

Hi,

Thank you for your quick answer.
It seems that the type Couchbase.Lite.IDictionary Object disappeared too. Do you confirm ?

Steeve

Disappeared? No it’s still there. The documentation page that I linked is for IDictionaryObject and it was generated from the db021 build.

Ok, I will try again. Thank you.

Hi,

I’m trying again to upgrate from db21 to DB21 of couchbase Lite 2.0, on Xamarin, c#.

Until then with the db19, I used to create a DictionaryObject for each of my model classes, like that

DictionaryObject dico = new DictionaryObject();

		dico.Set("table", Table);
		dico.Set("id", Id);
		dico.Set("aquereurPrincipal", AquereurPrincipal.DocumentInitialize());
		dico.Set("aquereurSecondaire", AquereurSecondaire.DocumentInitialize());
		dico.Set("adresse", Adresse.DocumentInitialize());
		dico.Set("situationFamiliale", SituationFamiliale);
		//dico.Set("dateSituation", DateSituation);
		dico.Set("lieuSituation", LieuSituation);
		dico.Set("commentaires", Commentaires);

		List<IDictionaryObject> listDictionaryFinancements = new List<IDictionaryObject>();
		foreach (Financement fin in Financements)
			listDictionaryFinancements.Add(fin.DocumentInitialize());
		dico.Set("financements", listDictionaryFinancements);

		List<IDictionaryObject> listDictionaryEnfants = new List<IDictionaryObject>();
		foreach (Enfant enfant in Enfants)
			listDictionaryEnfants.Add(enfant.DocumentInitialize());
		dico.Set("enfants", listDictionaryEnfants);

		dico.Set("vendeur", Vendeur.DocumentInitialize());

		return dico;

If I understood well, I Have to replace the DictionaryObject for a MutableDictionary, like that

MutableDictionary dico = new MutableDictionary();

		dico.SetString("table", Table);
		dico.SetString("id", Id);
		dico.SetDictionary("aquereurPrincipal", AquereurPrincipal.DocumentInitialize());
		dico.SetDictionary("aquereurSecondaire", AquereurSecondaire.DocumentInitialize());
		dico.SetDictionary("adresse", Adresse.DocumentInitialize());
		dico.SetString("situationFamiliale", SituationFamiliale);
		//dico.Set("dateSituation", DateSituation);
		dico.SetString("lieuSituation", LieuSituation);
		dico.SetString("commentaires", Commentaires);

		List<IDictionaryObject> listDictionaryFinancements = new List<IDictionaryObject>();
		foreach (Financement fin in Financements)
			listDictionaryFinancements.Add(fin.DocumentInitialize());
		dico.SetArray("financements", listDictionaryFinancements);

		List<IDictionaryObject> listDictionaryEnfants = new List<IDictionaryObject>();
		foreach (Enfant enfant in Enfants)
			listDictionaryEnfants.Add(enfant.DocumentInitialize());
		dico.SetArray("enfants", listDictionaryEnfants);

		dico.SetDictionary("vendeur", Vendeur.DocumentInitialize());

		return dico;

the problem is that the dico.SetDictionary don’t accept a IMutableDictionary, the dico.SetArray don’t accept a List.

What’s the proper way to correct that ?

Steeve

If you want to set data from .NET classes (IList<object> / IDictionary<string, object>), then the proper way now is SetData. The SetDictionary method accepts DictionaryObject (and by extension, MutableDictionary). So I assume your method is returning IMutableDictionary? Change it to return MutableDictionary instead.

Ok, Thank you Jim, I will try that.

Hi again,

It’ better for the compilation, I’ve this 2 new troubles

var query = Query.Select(SelectResult.All())
			.From(DataSource.Database(_dataBaseGetter.Get()))
			.Where(Expression.Property("table").EqualTo("commune").And(Expression.Property("libelle").Like($"{critereVille}%")))
			.OrderBy(Ordering.Property("libelle").Ascending())
			.Limit(limit);
			

		var rows = query.Run();

		return rows.Select(r => r.GetDictionary(0).ToCommune()).ToList();

The compilator said :
ILimit as not definition for ‘Run’
IWhere as not definition for "Run’

rows.Count don’t compile anymore.

And the last one about indexes

database.CreateIndex("TableI2", Index.ValueIndex().On(ValueIndexItem.Expression(Expression.Property("table"))));

the compilator said :
IValueIndex as not definition for ‘On’

What’s the proper way to correct that ?

About the réplicator, I assumed that I needed to use the new AddChangeListener methode in place of the event, is that correct ?

Steeve

I think I found the solution by myself :

IQuery query = Query.Select(SelectResult.All())
			.From(DataSource.Database(_dataBaseGetter.Get()))
			.Where(Expression.Property("table").EqualTo("commune").And(Expression.Property("libelle").Like($"{critereVille}%")))
			.OrderBy(Ordering.Property("libelle").Ascending())
			.Limit(limit);
			

		var rows = query.Execute();

		return rows.Select(r => r.GetDictionary(0).ToMutable().ToCommune()).ToList();

I changed the query type for IQuery, and find that there were a Execute methode, instead of Run.
And I called too ToMutable() from my Dictionnary to be able to call my personal extention class ToCommune().

About the indexes, I changed it like that

database.CreateIndex("TableI2",  Index.ValueIndex(ValueIndexItem.Expression(Expression.Property("table"))));

Don’t control It for now, but the compilator stopped crying …

Now, The replicator isn’t connecting anymore … I will begin another post.

Steeve