简体   繁体   中英

C# How to serialize/deserialize an Object to/from Dictionary<string,Object> to save/load it in Couchbase.lite

If I want to store data as Document in Clouchbase.lite is has to be in the form of Dictionary like this:

var properties = new Dictionary<string, object>()
    {
        {"type", "list"},
        {"title", "title"},
        {"created_at", DateTime.UtcNow.ToString ("o")},
        {"owner", "profile:" + userId},
        {"members", new List<string>()}
    };
var rev = document.PutProperties(properties);

How can I automatically create such a Dictionary from any C# object? If I understand the couchbase.lite documentation this process does not to be recursive, just on the first level of my object fields and properties.

How can I recreate my objects from such a dictionary?

Ok, this not a full answer to my question, but it solves the problem for now. I came to the solution of putting the whole object into the Dictionary that is handed to Couchbase.Lite:

    var c = new TestClass() {TestString = "SimpleStringfield", TestDate = DateTime.Today,TestStringProperty = "TestStringPropertyContent",
                              TestStringList = new List<string>(new string[] { "item1","item2","item3"})};


    var manager = Manager.SharedInstance;
    var db = manager.GetDatabase("test_database");
    if (db == null)
    {
        System.Diagnostics.Debug.WriteLine("--------------------------Could not open Database");
    }

    var doc = db.CreateDocument();
    var properties = new Dictionary<string,Object>() { {"type","day"}, {"day",c} };

    var rev = doc.PutProperties(properties);

    var docread = db.GetDocument(doc.Id);
    JObject testobject = (JObject)docread.GetProperty("day");

    var o = testobject.ToObject<TestClass>();
}

At the end o contains the same values as c.

I want to point out the warning that Jim Borden gave me to this approach:

I will always assert that the "right way" is the way that works. The fact that the library uses JSON .NET internally is an implementation detail, though. If that were to change for some reason then this way would break. I also have a feeling that if the class were more complex than your example than it would break as well. We are currently designing a cross platform specification to do just what you want to do (save classes directly to the database without converting to a dictionary first). This will be a slow process though because there is a lot of thought that needs to go into it (not just for C#, but for Java and Objective-C as well). For example, how to serialize a class that has a property which references back to it, etc. I know JSON .NET already does this, but I don't want to start exposing JSON .NET into the public API because eventually it should be switchable (in case JSON .NET does not work for whatever reason on a platform).

I know you are talking about automatic, but I needed the individual fields of my class to be exposed so I can index them and run mapped queries. So I specified all my query-able objects to follow this interface:

public interface IEntity
{
    string Id { get; set; }

    IDictionary<string, object> ToDictionary();
    void PopulateFrom(IDictionary<string, object> prop);

}

And typically implemented as follows:

public class Club : IEntity
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Country { get; set; }
    public string Place { get; set; }
    public long ClubId { get; set; }
    public string Access { get; set; } = "read";
    public List<ClubMember> Members { get; set; }

    public void PopulateFrom(IDictionary<string, object> prop)
    {
        Name = prop.GetOrDefault<string>("name");
        Country = prop.GetOrDefault<string>("country");
        Place = prop.GetOrDefault<string>("place");
        ClubId = prop.GetOrDefault<long>("club_id");
        Access = prop.GetOrDefault<string>("access");
        Members = ParseMembers(prop["members"]);
    }


    public IDictionary<string, object> ToDictionary()
    {

        return new Dictionary<string, object>
        {
            { "club_id", ClubId },
            { "name", Name },
            { "country", Country },
            { "place", Place },
            { "access", Access },
            { "members", Members}
        };
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM