{"id":21097459,"url":"https://github.com/emerbrito/dataverse-extensions-data","last_synced_at":"2025-10-27T09:15:31.469Z","repository":{"id":84522396,"uuid":"588218003","full_name":"emerbrito/dataverse-extensions-data","owner":"emerbrito","description":"A convention-based entity to object mapper (table to object) plus additional data utilities for Dateverse client applications and plugins plugin development.","archived":false,"fork":false,"pushed_at":"2023-01-14T20:02:48.000Z","size":69,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-05T02:50:25.899Z","etag":null,"topics":["common-data-service","dataverse","dataverse-serviceclient","dynamics","dynamics-365","dynamics-crm","powerapps","powerplatform"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/emerbrito.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":"2023-01-12T15:53:57.000Z","updated_at":"2023-01-13T05:11:12.000Z","dependencies_parsed_at":"2023-03-04T04:15:35.460Z","dependency_job_id":null,"html_url":"https://github.com/emerbrito/dataverse-extensions-data","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/emerbrito/dataverse-extensions-data","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emerbrito%2Fdataverse-extensions-data","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emerbrito%2Fdataverse-extensions-data/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emerbrito%2Fdataverse-extensions-data/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emerbrito%2Fdataverse-extensions-data/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/emerbrito","download_url":"https://codeload.github.com/emerbrito/dataverse-extensions-data/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emerbrito%2Fdataverse-extensions-data/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":281243514,"owners_count":26467709,"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","status":"online","status_checked_at":"2025-10-27T02:00:05.855Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["common-data-service","dataverse","dataverse-serviceclient","dynamics","dynamics-365","dynamics-crm","powerapps","powerplatform"],"created_at":"2024-11-19T22:48:20.230Z","updated_at":"2025-10-27T09:15:31.439Z","avatar_url":"https://github.com/emerbrito.png","language":"C#","readme":"# EmBrito.Dataverse.Extensions.Data\n\n[![Nuget](https://img.shields.io/nuget/v/EmBrito.Dataverse.Extensions.Data)](https://www.nuget.org/packages/EmBrito.Dataverse.Extensions.Data)\n![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/emerbrito/dataverse-extensions-data/dotnet-build.yml)\n\nData utilities for Dateverse client applications and plugin development.\n\n# Entity Mappings\n\nPerforms data transformation between an entity (table) and a business object (such as a DTO). A common use case is when you need to map an entity to a dto, serialize and send it to an external API. In this document:\n\n- [Basic Usage](#basic-usage)\n- [Using Formatted Values](#using-formatted-values)\n- [Applying String Format](#applying-string-format)\n- [Mapping Multiple Choice Columns](#mapping-multiple-choice-columns)\n- [Mapping Entity Collection Columns](#mapping-entity-collection-columns)\n- [Mapping Entity Reference Columns](#mapping-entity-reference-columns)\n- [Mapping Entity Reference Collection Columns](#mappinge-entity-reference-collection-columns)\n- [Custom Converters](#custom-converters)\n- [Data Mapping Attributes](#data-mapping-attributes)\n- [Dataverse Column to .net Types](#dataverse-column-to-net-types)\n\n## Basic Usage\n\nTo perform data mapping and transformation your DTO must extend the `EntityMapper` class.\nMapping is done by decorating each mapped property with a corresponding attribute.\n\nA simple example:\n\n``` csharp\npublic class AccountDto : EntityMapper\u003cAccountDto\u003e\n{\n    [FromStringColumn(\"name\")]\n    public string Name { get; set; }\n\n    [FromOptionSetColumn(\"industrycode\", formattedValue: true)]\n    public string IndustryCode { get; set; }\n\n    [FromCurrencyColumn(\"openrevenue\")]\n    public decimal? Revenue { get; set; }\n\n    [FromOptionSetColumn(\"statecode\")]\n    public int State { get; set; }\n\n    public AccountDto(Entity entity) : base(entity)\n    {\n    }\n}\n```\n\nIn this example an instance of the DTO is created from an account entity and then serialized to JSON:\n\n``` csharp\nEntity account = crmServiceClient.Retrieve(\"account\", accountId, new ColumnSet(true));\nAccountDto dto = new AccountDto(account);\n\n// serializing the mapped object\nstring jsonString = JsonSerializer.Serialize(dto);\n```\nThe JSON should look like this:\n\n``` json\n{\n    \"Name\": \"Contoso\",\n    \"IndustryCode\": \"Business Services\",\n    \"Revenue\": 3000000,\n    \"AccountState\": 1\n}\n```\n\nSee the following sections for additional details on data transformation.\n\n## Using Columns Formatted Value\n\nSome dataverse columns such as numbers, dates and currency have built in support for formatted values. The formatted value of an option set (choice) is its label.\n\nThe use the formatted value, map to a string property and set the `formattedValue` parameter to `true`.\n\n``` csharp\n// returns the option set label\n[FromOptionSetColumn(\"statecode\", formattedValue: true)]\npublic string Status { get; set; }\n\n// returns the formatted date\n[FromDateTimeColumn(\"modifiedon\", formattedValue: true)]\npublic string DateModified { get; set; }\n\n// returns the formatted currency value\n[FromCurrencyColumn(\"annualrevenue\", formattedValue: true)]\npublic string Revenue { get; set; }\n```\n\n## Applying String Format\n\nSome attributes will support a string format parameter.\nWhen provided, this format will be applied to the output string.\nMore information on supported formats can be found here: [How to format numbers, dates, enums, and other types in .NET][1]\n\n``` csharp\n// sample output: 2023-10-25\n[FromDateTimeColumn(\"modifiedon\",format: \"yyyy-MM-dd\")]\npublic string DateModified { get; set; }\n\n// sample output: \n[FromCurrencyColumn(\"annualrevenue\", format: \"C3\")]\npublic string Revenue { get; set; }\n```\n\n## Mapping Multiple Choice Columns\n\nThe output of a multiple choices columns is controlled by the attribute paramaters and the property type.\n\n``` csharp\n\n// The examples using a List\u003cT\u003e (int or string) could also be replaced with arrays of the equivalent type.\n\n// Returns a list of numbers with the value from each selection.\n[FromOptionSetCollectionColumn(\"new_subscription\")]\npublic List\u003cint\u003e Subscriptions { get; set; }\n\n// Returns a list of strings with the numeric value from each selection.\n[FromOptionSetCollectionColumn(\"new_subscription\")]\npublic List\u003cstring\u003e Subscriptions { get; set; }\n\n// Returns a list of strings with the label from each selection.\n[FromOptionSetCollectionColumn(\"new_subscription\", formattedValue: true)]\npublic List\u003cstring\u003e Subscriptions { get; set; }\n\n// Returns a comma separated string with the numeric value of all selected items.\n[FromOptionSetCollectionColumn(\"new_subscription\")]\npublic string Subscriptions { get; set; }\n\n// Returns a comma separated string with the label from all selected items.\n[FromOptionSetCollectionColumn(\"new_subscription\", formattedValue: true)]\npublic string Subscriptions { get; set; }\n\n```\n\n## Mapping Entity Collection Columns\n\nSome columns such as Activity Party returns an entity collection. The output will always be the ID property of each entity which could be represented by the following types:\n\n- Guid[]\n- List\u003cGuid\u003e\n- string[] (Guid as string)\n- List\u003cstring\u003e (Guid as string)\n\n```csharp\n[FromEntityCollectionColumn(\"to\")]\npublic List\u003cGuid\u003e EmailTo { get; set; }\n```\n\n## Mapping Entity Reference Columns\nEntity reference columns can output their id as Guid or string and their formatted value (the primary name column of the corresponding entity).\n\n``` csharp\n// Outputs entity reference id\n[FromEntityReferenceColumn(\"parentaccountid\")]\npublic Guid? ParentAccount { get; set; }\n\n// Outputs entity reference id as string\n[FromEntityReferenceColumn(\"parentaccountid\")]\npublic string ParentAccount { get; set; }\n\n// Outputs entity reference formatted value (the primary name column)\n[FromEntityReferenceColumn(\"parentaccountid\", formattedValue: true)]\npublic string ParentAccount { get; set; }\n```\n\n## Mapping Entity Reference Collection Columns\n\nEntity reference collection columns can output their id as Guid or string and their formatted value (the primary name column of the corresponding entity).\n\n- Guid[]\n- List\u003cGuid\u003e\n- string[] (Guid as strings)\n- List\u003cstring\u003e (Guid as strings)\n- List\u003cstring\u003e (primary name when formattedValue is true)\n- string (comma separate list of primary name when formattedValue is true)\n\n## Custom Converters\n\nYou can apply custom data transformation to handle specific business scenarions. Form example, you may need to return different labels for an option set than what you get from formatted values.\n\n``` csharp\npublic class AccountDto : EntityMapper\u003cAccountDto\u003e\n{\n    public AccountDto(Entity entity) : base(entity)\n    {\n    }\n    \n    [FromOptionSetColumn(\"accounttype\")]\n    public string AccountType { get; set; }\n\n    // Ovveride the Configure method to specify custom converter for specific fields\n    protected override void Configure(EntityMapperOptions options)\n    {\n        options.AddConverter(\"accounttype\", AccountTypeConverter);\n    }\n\n    object AccountTypeConverter(MappedProperty mappingInfo, Entity entity)\n    {\n        var choice = entity.GetAttributeValue\u003cOptionSetValue\u003e(\"accounttype\");        \n        return choice.Value == 2 ? \"Premium\" : \"Standard\"        \n    }\n\n}\n```\n\n## Data Mapping Attributes\n\nThe attribute name is self explanatory and should match the column type you are mapping from.\nThe property type will determine the desired output, or the type you are mapping to.\n\nBelow is a list of all available attributes the the supported output type.\n\n\u003e Columns mapped to a string property may output  their primitive values, the column formatted value from the dataverse or a formatted string when a format parameter is provided. Support for each option is based on the attribute type. A `formattedValue` paramter will be available in the attribute when supported.\n\n### FromBooleanColumn\n\n- Boolean\n- Integer\n- String (will display true, false or the option set label)\n\n### FromCurrencyColumn\n\n- Decimal\n- String\n\n### FromDateTimeColumn\n\n- DateTime\n- String\n\n### FromDecimalColumn\n\nConversion to other numeric types or boolean will be performed based on the value.\nIf the value cannot be converted an exception will be thrown.\n\n- Bool\n- Decimal\n- Double\n- Float\n- Int\n- String\n\n### FromDoubleColumn\n\nConversion to other numeric types or boolean will be performed based on the value.\nIf the value cannot be converted an exception will be thrown.\n\n- Bool\n- Decimal\n- Double\n- Float\n- Int\n- String\n\n### FromEntityCollectionColumn\n\n- Array\u003cGuid\u003e\n- Array\u003cstring\u003e (Guid will be converted to string)\n- List\u003cGuid\u003e\n- List\u003cstring\u003e (Guid will be converted to string)\n\n### FromEntityReferenceCollectionColumn\n\n- Array\u003cGuid\u003e\n- Array\u003cstring\u003e (Guid will be converted to string)\n- List\u003cGuid\u003e\n- List\u003cstring\u003e (Guid will be converted to string)\n\n### FromEntityReferenceColumn\n\n- Guid\n- String\n\n### FromImageColumn\n\n- byte[] (the original byte array returned by as the column value).\n- String (a base64 string representing the byte[])\n\n### FromIntegerColumn\nConversion to other numeric types or boolean will be performed based on the value.\nIf the value cannot be converted an exception will be thrown.\n\n- Bool\n- Decimal\n- Double\n- Float\n- Int\n- String\n\n### FromOptionSetCollectionColumn\n\n- Array\u003cint\u003e\n- Array\u003cstring\u003e (With numeric values or option set labels)\n- List\u003cint\u003e\n- List\u003cstring\u003e (With numeric values or option set labels)\n\n### FromOptionSetColumn\n\nConversion to other numeric types besides decimal, or boolean will be performed based on the value. If the value cannot be converted an exception will be thrown.\n\n- Bool\n- Decimal\n- Double\n- Float\n- Int\n- String (numeric value or option set label)\n\n### FromStringColumn\nConversion to numeric types, boolean or DateTime will be performed based on the value.\nIf the value cannot be converted an exception will be thrown.\n\n- Bool\n- Decimal\n- DateTime\n- Double\n- Float\n- Int\n- String\n\n### FromUniqueIdentifierColumn\n\n- Guid\n- String (Guid converted to a string)\n## Dataverse Column Type to .net Types\n\nThe following table is meant for reference only.\nIt indicates how the dataverse columns are mapped to .net types by the PowerPlatform SDK.\nIt also indicates the column types that have native support for formatted values.\n\n| Column Type | .net type | Formatted Value Support\u003csup\u003e1\u003c/sup\u003e |\n|-------------|-----------|-------------------------|\n| Activity Party | EntityCollection\u003csup\u003e2\u003c/sup\u003e | |\n| Auto Number | string | |\n| Currency | Money | Yes |\n| Customer | EntityReference | Yes |\n| Date and Time | DateTime | Yes |\n| Decimal | decimal | Yes |\n| Duration | Int32 | Yes |\n| File | Guid | |\n| Float | Double | Yes |\n| Image | byte[] | |\n| Language Code | Int32 | Yes |\n| Lookup | EntityReference | Yes |\n| Multiple Lines of Text | string | |\n| MultiSelect Option Set (Choice) | OptionSetValueCollection | Yes |\n| Option Set (Choice) | OptionSetValue | Yes |\n| Owner | EntityReference | Yes |\n| Single Line of Text | string | |\n| Status | OptionSetValue | Yes |\n| Status Reason | OptionSetValue | Yes |\n| Time Zone | Int32 | Yes |\n| Ticker Symbol | string | |\n| Two Options | bool | Yes |\n| Unique Identifier | Guid | |\n| Whole Number | Int32 | Yes |\n\n\u003csup\u003e1\u003c/sup\u003e Whether a string representing a formatted value is also returned by query expressions.\n\u003csup\u003e2\u003c/sup\u003e An Activity Party column will return an entity collection of `actvityparty`. The `partyid` column of each returned entity will contain an `EntityReference` to the actual record.\n\n[1]: https://learn.microsoft.com/en-us/dotnet/standard/base-types/formatting-types\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femerbrito%2Fdataverse-extensions-data","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Femerbrito%2Fdataverse-extensions-data","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femerbrito%2Fdataverse-extensions-data/lists"}