{"id":23577507,"url":"https://github.com/couchbaselabs/couchbase.lite.mapping","last_synced_at":"2025-05-05T23:14:50.685Z","repository":{"id":37924472,"uuid":"174547441","full_name":"couchbaselabs/Couchbase.Lite.Mapping","owner":"couchbaselabs","description":"A simple library that extends Couchbase.Lite to provide extension methods for converting an object to a Document/MutableDocument and a Document/MutableDocument to an object.","archived":false,"fork":false,"pushed_at":"2023-09-18T23:30:10.000Z","size":1862,"stargazers_count":20,"open_issues_count":11,"forks_count":7,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-05-05T23:14:43.209Z","etag":null,"topics":["couchbase-community","couchbase-lite","couchbase-mobile","dotnet","mobile","nosql","nuget","xamarin","xamarin-android","xamarin-forms","xamarin-ios","xamarin-uwp"],"latest_commit_sha":null,"homepage":"https://www.couchbase.com/products/lite","language":"C#","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/couchbaselabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-03-08T14:01:49.000Z","updated_at":"2025-04-26T17:51:11.000Z","dependencies_parsed_at":"2024-06-19T16:31:28.917Z","dependency_job_id":"c24fc094-ae80-4e0e-93aa-9f8cdcd860a4","html_url":"https://github.com/couchbaselabs/Couchbase.Lite.Mapping","commit_stats":{"total_commits":55,"total_committers":5,"mean_commits":11.0,"dds":"0.10909090909090913","last_synced_commit":"70863e6d0dbc420a0d845f19c993bfb8b4ce84f9"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/couchbaselabs%2FCouchbase.Lite.Mapping","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/couchbaselabs%2FCouchbase.Lite.Mapping/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/couchbaselabs%2FCouchbase.Lite.Mapping/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/couchbaselabs%2FCouchbase.Lite.Mapping/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/couchbaselabs","download_url":"https://codeload.github.com/couchbaselabs/Couchbase.Lite.Mapping/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252590633,"owners_count":21772940,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["couchbase-community","couchbase-lite","couchbase-mobile","dotnet","mobile","nosql","nuget","xamarin","xamarin-android","xamarin-forms","xamarin-ios","xamarin-uwp"],"created_at":"2024-12-26T22:29:22.599Z","updated_at":"2025-05-05T23:14:50.668Z","avatar_url":"https://github.com/couchbaselabs.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"**This is an independent, open source couchbaselabs project, and is NOT officially supported by Couchbase, Inc.  Issues are disabled, but if you post a question on the [forums](https://www.couchbase.com/forums/) you might get an answer.**\n\n# Couchbase.Lite.Mapping\n\n`Couchbase.Lite.Mapping` gives developers the ability to dynamically automatically convert generic objects to/from Couchbase `Document` objects and lists of `Result` objects. This drastically reduces the amount of, often repeated, code needed to be written to store and retrieve information to and from Couchbase Lite databases.\n\n# Table of Contents\n1. [Getting Started](#gettingstarted)\n2. [Building the Project (optional)](#build)\n3. [Basic Usage: Object/Document](#basicusage1)\n4. [Basic Usage: IResultSet to Object(s)](#basicusage2)\n5. [Advanced Usage: IResultSet to Object(s)](#advusage)\n6. [Customizing Property Name Serialization](#custom-property-serialization)\n    1. [Globally](#custom-property-serialization-global)\n    2. [By Document](#custom-property-serialization-document)\n    3. [By Property](#custom-property-serialization-property)\n7. [Testing](#testing)\n\n### Getting Started \u003ca name=\"gettingstarted\"\u003e\u003c/a\u003e\n\n**NOTE:**\nAs of version 1.0.2, in order to use `Couchbase.Lite.Mapping` you must have either the [Couchbase.Lite](https://www.nuget.org/packages/Couchbase.Lite/) or [Couchbase.Lite.Enterprise](https://www.nuget.org/packages/Couchbase.Lite/) package installed.\n\n`Couchbase.Lite.Mapping` does **not** include dependencies so that it can work with both `Couchbase.Lite` and `Couchbase.Lite.Enterprise`. This also provides the flexibility to install any compatible version of Couchbase.lite.\n\n`Couchbase.Lite.Mapping` is available via:\n* NuGet Official Releases: [![GitHub release](https://img.shields.io/nuget/v/Couchbase.Lite.Mapping.svg?style=plastic)](https://www.nuget.org/packages/Couchbase.Lite.Mapping)\n\n\n### Build (optional) \u003ca name=\"build\"\u003e\u003c/a\u003e\nIf you would like to build the package from source instead, follow the steps below\n\n- Clone the repo\n```\ngit clone https://github.com/couchbaselabs/Couchbase.Lite.Mapping\n```\n- Build the release version of project using Visual Studio\n- Build the package\n```\ncd /path/to/repo/src/Couchbase.Lite.Mapping/packaging/nuget\n\nnuget pack Couchbase.Lite.Mapping.nuspec\n```\n\n### Documentation \u003ca name=\"documentation\"\u003e\u003c/a\u003e\n\nTo get started using [Couchbase.Lite](https://github.com/couchbase/couchbase-lite-net) or [Couchbase.Lite.Enterprise](https://www.nuget.org/packages/Couchbase.Lite.Enterprise/) please refer to the [official documentation](https://developer.couchbase.com/documentation/mobile/2.0/guides/couchbase-lite/index.html).\n\n\n### Basic Usage: Object/Document \u003ca name=\"basicusage1\"\u003e\u003c/a\u003e\n\nCreate a new document with a new object.\n```csharp\n// An object to be converted to a document\npublic class Person\n{\n    public string FirstName { get; set; }\n    public string LastName { get; set; }\n}\n\n// Create an instance of the object\nvar person = new Person\n{\n    FirstName = \"Clark\",\n    LastName = \"Kent\"\n};\n\n// Convert the object into a Couchbase.Lite MutableDocument\nvar newMutableDocument = person.ToMutableDocument();\n\n// Convert a Couchbase.Lite MutableDocument into an object (of a type specified via generic)\nvar newPerson = newMutableDocument.ToObject\u003cPerson\u003e();\n```\n\nModify an existing document.\n```csharp\n// You can provide the document ID to the ToMutableDocument extension method\n// Where \"person\" is a previously retrieved (and mapped) document, and \"id\" is a known document ID.\nvar existingMutableDocument = person.ToMutableDocument($\"person::{id}\"); \n```\n\n**Note:** The `ToMutableDocument` extension method also \n\n### Basic Usage: IResultSet to Object(s) \u003ca name=\"basicusage2\"\u003e\u003c/a\u003e\n\n#### Default (old) approach\n```csharp\nvar query = QueryBuilder.Select(SelectResult.All()) \n                                        .From(DataSource.Database(database)) \n                                        .Where(whereQueryExpression); \n                                        \nvar results = query?.Execute()?.AllResults();\n\nif (results?.Count \u003e 0)\n{\n    personList = new List\u003cPerson\u003e();\n\n    foreach (var result in results)\n    {\n        // Where 'people' is the containing Dictionary key\n        var dictionary = result.GetDictionary(\"people\");\n\n        if (dictionary != null)\n        {\n            var person = new Person\n            {\n                FirstName = dictionary.GetString(\"firstName\"), \n                LastName = dictionary.GetString(\"lastName\") \n            };\n\n            personList.Add(person);\n        }\n    }\n}\n```\n#### Couchbase.Lite.Mapping approach\n```csharp\nvar query = QueryBuilder.Select(SelectResult.All()) \n                                        .From(DataSource.Database(database)) \n                                        .Where(whereQueryExpression); \n\nvar results = query?.Execute()?.AllResults();\n\n// Map all of the results to a list of objects\nvar personList = results?.ToObjects\u003cPerson\u003e(); \n\n// OR map a single result item to an object\nvar person = results?[0].ToObject\u003cPerson\u003e();\n\n```\n\n### Advanced Usage: IResultSet to Object(s)\u003ca name=\"advusage\"\u003e\u003c/a\u003e\n\nYou can also map more complex queriies. \n\nReturning Meta ID (and any other valid column)\n```csharp\npublic class Person\n{ \n    public string Type =\u003e \"person\";\n    public string Id { get; set; }\n    public string FirstName { get; set; }\n    public string LastName { get; set; }\n}\n\nvar query = QueryBuilder.Select(SelectResult.Expression(Meta.ID), SelectResult.All())\n            .From(DataSource.Database(Database))\n            .Where(Expression.Property(\"type\").EqualTo(Expression.String(\"person\")));\n\nvar results = query?.Execute()?.AllResults();\n\nvar people = results?.ToObjects\u003cPerson\u003e();\n```\n\nData aggregation\n```csharp\npublic class PersonStats\n{ \n    public int Count { get; set; }\n    public string Type { get; set; }\n}\n\nvar query = QueryBuilder.Select(\n                        SelectResult.Expression(Function.Count(Expression.All())).As(\"count\"),\n                        SelectResult.Property(\"type\"))\n                       .From(DataSource.Database(Database))\n                       .Where(Expression.Property(\"type\").NotNullOrMissing())\n                       .GroupBy(Expression.Property(\"type\"))\n                       .OrderBy(Ordering.Property(\"type\").Ascending());\n\nvar results = query?.Execute()?.AllResults();\n\nvar personStats = results?[0].ToObjects\u003cPersonStats\u003e(); \n```\n\n### Customizing Property Name Serialization \u003ca name=\"custom-property-serialization\"\u003e\u003c/a\u003e\n\nThe default serialization for object property names into Couchbase Lite databases uses **Lower Camel Case** (e.g. lowerCamelCase).\n\nBy default the following object\n```csharp\nvar person = new Person\n{\n    FirstName = \"Bruce\",\n    LastName = \"Wayne\"\n};\n```\nwill look like the following in JSON.\n\n```json\n{\n    \"firstName\": \"Bruce\",\n    \"lastName\": \"Wayne\"\n}\n```\n*Note the casing of `firstName` and `lastName`.*\n\n#### Globally \u003ca name=\"custom-property-serialization-global\"\u003e\u003c/a\u003e\nYou can override the default implementation of `IPropertyNameConverter` by setting `Couchbase.Lite.Mapping.Setting.PropertyNameConverter`.\n\n```csharp\nusing Couchbase.Lite.Mapping;\n...\n\n// Set this value to override the default IPropertyNameConverter\nSettings.PropertyNameConverter = new CustomPropertyNameConverter();\n\n// Here's an example of a custom implementation of IPropertyNameConverter\npublic class CustomPropertyNameConverter : IPropertyNameConverter\n{\n    public string Convert(string propertyName)\n    {\n      return propertyName.ToUpper();\n    }\n}\n```\n\nUsing `CustomerPropertyNameConverter` will yield the following JSON seralization for `Person`.\n\n```json\n{\n    \"FIRSTNAME\": \"Bruce\",\n    \"LASTNAME\": \"Wayne\"\n}\n```\n\n#### By Document \u003ca name=\"custom-property-serialization-document\"\u003e\u003c/a\u003e\n\nYou can override the default implementation of `IPropertyNameConverter` at the document level by passing in an instance of a class that implements `IPropertyNameConverter` into the `ToMutableDocument` extension method.\n\n```csharp\nvar mutableDocument = testObject.ToMutableDocument(new CustomPropertyNameConverter());\n```\n\n#### By Property \u003ca name=\"custom-property-serialization-property\"\u003e\u003c/a\u003e\n\nYou can override the default implementation of `IPropertyNameConverter` at the property level by adding a `MappingPropertyName` attribute above a property.\n\n```csharp\nusing Couchbase.Lite.Mapping;\n\npublic class Person\n{\n    [MappingPropertyName(\"fIRStNaME\")]\n    public string FirstName { get; set; }\n\n    // This property will be converted using the default converter\n    public string LastName { get; set; }\n}\n```\n\nUsing `MappingPropertyName` (like above) will yield the following JSON seralization for `Person`.\n\n```json\n{\n    \"fIRStNaME\": \"Diana\",\n    \"lastName\": \"Prince\"\n}\n```\n\n## Testing \u003ca name=\"testing\"\u003e\u003c/a\u003e\n\n### Sample App \n\nA sample Xamarin.Forms solution (supporting iOS and Android) can be found within [Samples](https://github.com/couchbaselabs/Couchbase.Lite.Mapping/tree/master/sample/Couchbase.Lite.Mapping.Sample). Simply clone this repo, open [Couchbase.Lite.Mapping.Sample.sln](https://github.com/couchbaselabs/Couchbase.Lite.Mapping/blob/master/sample/Couchbase.Lite.Mapping.Sample/Couchbase.Lite.Mapping.Sample.sln), and build/run the application!\n\nThe sample app allows users to log in with _any_ username and password, and maintains a user profile per username. Profiles consist of basic information and an image that is persisted as a user profile Document in the Couchbase Lite database for a \"logged in\" user.\n\n\u003cp\u003e\n  \u003cimg src=\"images/login.png\" width=\"200\" title=\"hover text\" style=\"margin-right:25px;\" border=\"3px\"\u003e\n  \u003cimg src=\"images/profile.png\" width=\"200\" alt=\"accessibility text\" border=\"5px\"\u003e\n\u003c/p\u003e\n\n## Contributors ##\nCouchbase.Lite.Mapping is an open source project and community contributions are welcome whether they be pull-requests, feedback or filing bug tickets or feature requests.\n\n**Please include appropriate unit tests with pull-requests.**\n\nWe appreciate any contribution no matter how big or small!\n\n## Licenses ##\nThe mapping package is available under\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg?style=plastic)](https://opensource.org/licenses/Apache-2.0)\n \n**Note:**: \nUse of `Couchbase.Lite.Mapping` has no implications on the `Couchbase.Lite.Enterprise` or `Couchbase.Lite` licenses. Those packages are governed by the terms of the Couchbase Enterprise Edition and Community Edition licenses respectively\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcouchbaselabs%2Fcouchbase.lite.mapping","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcouchbaselabs%2Fcouchbase.lite.mapping","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcouchbaselabs%2Fcouchbase.lite.mapping/lists"}