![]() |
VOOZH | about |
dotnet add package Rystem.RepositoryFramework.Infrastructure.Dynamics.Dataverse --version 10.0.8
NuGet\Install-Package Rystem.RepositoryFramework.Infrastructure.Dynamics.Dataverse -Version 10.0.8
<PackageReference Include="Rystem.RepositoryFramework.Infrastructure.Dynamics.Dataverse" Version="10.0.8" />
<PackageVersion Include="Rystem.RepositoryFramework.Infrastructure.Dynamics.Dataverse" Version="10.0.8" />Directory.Packages.props
<PackageReference Include="Rystem.RepositoryFramework.Infrastructure.Dynamics.Dataverse" />Project file
paket add Rystem.RepositoryFramework.Infrastructure.Dynamics.Dataverse --version 10.0.8
#r "nuget: Rystem.RepositoryFramework.Infrastructure.Dynamics.Dataverse, 10.0.8"
#:package Rystem.RepositoryFramework.Infrastructure.Dynamics.Dataverse@10.0.8
#addin nuget:?package=Rystem.RepositoryFramework.Infrastructure.Dynamics.Dataverse&version=10.0.8Install as a Cake Addin
#tool nuget:?package=Rystem.RepositoryFramework.Infrastructure.Dynamics.Dataverse&version=10.0.8Install as a Cake Tool
Rystem.RepositoryFramework.Infrastructure.Dynamics.Dataverse adds a Microsoft Dataverse adapter for Repository Framework.
It auto-provisions a Dataverse table for your model, but the storage model is much simpler than a typical Dataverse-first mapping: every repository property is stored as a string column, and most queries run in memory after fetch.
dotnet add package Rystem.RepositoryFramework.Infrastructure.Dynamics.Dataverse
For each registered model, the package works with one Dataverse table.
Prefix + TableName.ToLower()Prefix + PrimaryKey.ToLower()So this package uses Dataverse mainly as a managed record store, not as a strongly typed Dataverse-schema translator.
Available on all three patterns:
WithDataverse(...)Supported for:
IRepositoryBuilder<T, TKey>ICommandBuilder<T, TKey>IQueryBuilder<T, TKey>This matches the repository API tests.
builder.Services.AddRepository<CalamityUniverseUser, string>(repositoryBuilder =>
{
repositoryBuilder.WithDataverse(dataverseBuilder =>
{
dataverseBuilder.Settings.Prefix = "repo_";
dataverseBuilder.Settings.SolutionName = "Solution001";
dataverseBuilder.Settings.TableName = "CalamityUniverseUser";
dataverseBuilder.Settings.SetConnection(
builder.Configuration["Dataverse:Environment"]!,
new DataverseAppRegistrationAccount(
builder.Configuration["Dataverse:ClientId"]!,
builder.Configuration["Dataverse:ClientSecret"]!));
});
});
Example model from the tests:
public sealed class CalamityUniverseUser
{
public string? Id { get; set; }
public string? Name { get; set; }
public string? Email { get; set; }
public int Port { get; set; }
public bool IsAdmin { get; set; }
public Guid GroupId { get; set; }
}
IDataverseRepositoryBuilder<T, TKey> exposes:
| Member | Purpose |
|---|---|
Settings |
Connection and Dataverse table settings |
WithColumn(expr, customPrefix) |
Override the prefix used for one property |
DataverseOptions<T, TKey> exposes:
| Property | Default | Notes |
|---|---|---|
Prefix |
new_ |
Global prefix for the logical table and column names |
TableName |
typeof(T).Name |
Display and schema base name |
PrimaryKey |
Id |
Name of the Dataverse primary attribute used to store the repository key |
SolutionName |
null |
Used when creating a new table |
Description |
null |
Falls back to an auto-generated description |
Environment |
required | Set through SetConnection(...) |
ApplicationIdentity |
required | Set through SetConnection(...) |
Use:
dataverseBuilder.Settings.SetConnection(
environment,
new DataverseAppRegistrationAccount(clientId, clientSecret));
Internally the package creates a ServiceClient with a client-secret connection string like:
Url=https://{Environment}.dynamics.com;AuthType=ClientSecret;ClientId=...;ClientSecret=...;RequireNewInstance=true
This package currently documents and implements only the app-registration client-secret path.
WithDataverse(...) automatically registers a warm-up action.
At startup, BootstrapAsync():
StringAttributeMetadataYou should still run:
await app.Services.WarmUpAsync();
That is the path the repository expects for auto-provisioning.
When the table is created:
UserOwned100When model properties are created:
1002000So even if your .NET property is int, bool, Guid, or a complex object, the stored Dataverse attribute is still a string attribute.
The repository key TKey is stored in the Dataverse primary attribute column.
TKey values are stored with ToString()TKey values are stored as JSONImportant nuance:
PrimaryKey config controls the Dataverse primary attribute nameFor example, the tests register CalamityUniverseUser with TKey = string, while the Dataverse table still uses the default logical primary attribute based on Id.
QueryAsync(...) is mostly client-side.
The repository issues a Dataverse query with:
TopCount = 100ColumnSetThen it:
Entity<T, TKey> valuesPractical consequence:
Where, ordering, paging, and aggregates all operate on the fetched in-memory subsetQueryAsync(...)Key-based methods do use Dataverse-side filtering.
GetAsync, ExistAsync, UpdateAsync, and DeleteAsync query by the logical primary key columnInsertAsync creates a new Dataverse row directlyUpdateAsync first finds the existing Dataverse row and then updates it by Dataverse row id.
BatchAsync(...) is a sequential loop over insert/update/delete operationsCount, Sum, Min, Max, and Average run in memory after QueryAsync(...)WithColumn(x => x.Property, customPrefix: "...") exists, but the current implementation is less reliable than the API suggests.
Important source-backed caveats:
ColumnSet is built before WithColumn(...) overrides the property prefixSo per-column custom prefixes may not behave consistently across provisioning and reads. If you need robust mappings, prefer a single global Prefix for the whole table.
SolutionName is used when creating a new Dataverse table.
The current implementation does not perform a broader ongoing solution-management workflow for already existing tables or attributes.
builder.Services.AddCommand<AccountModel, string>(commandBuilder =>
{
commandBuilder.WithDataverse(dataverseBuilder =>
{
dataverseBuilder.Settings.Prefix = "repo_";
dataverseBuilder.Settings.SetConnection(
builder.Configuration["Dataverse:Environment"]!,
new DataverseAppRegistrationAccount(
builder.Configuration["Dataverse:ClientId"]!,
builder.Configuration["Dataverse:ClientSecret"]!));
});
});
builder.Services.AddQuery<AccountModel, string>(queryBuilder =>
{
queryBuilder.WithDataverse(dataverseBuilder =>
{
dataverseBuilder.Settings.Prefix = "repo_";
dataverseBuilder.Settings.SetConnection(
builder.Configuration["Dataverse:Environment"]!,
new DataverseAppRegistrationAccount(
builder.Configuration["Dataverse:ClientId"]!,
builder.Configuration["Dataverse:ClientSecret"]!));
});
});
Use it when you want:
Avoid it when you need deep Dataverse-native query translation or strongly typed Dataverse attribute mapping, because the current implementation is intentionally much thinner than that.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
This package is not used by any NuGet packages.
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 10.0.8 | 5,454 | 5/13/2026 |
| 10.0.7 | 94 | 3/26/2026 |
| 10.0.6 | 433,516 | 3/3/2026 |
| 10.0.5 | 88 | 2/22/2026 |
| 10.0.4 | 94 | 2/9/2026 |
| 10.0.3 | 147,889 | 1/28/2026 |
| 10.0.1 | 209,057 | 11/12/2025 |
| 9.1.3 | 233 | 9/2/2025 |
| 9.1.2 | 764,458 | 5/29/2025 |
| 9.1.1 | 97,817 | 5/2/2025 |
| 9.0.32 | 186,681 | 4/15/2025 |
| 9.0.31 | 5,789 | 4/2/2025 |
| 9.0.30 | 88,840 | 3/26/2025 |
| 9.0.29 | 9,031 | 3/18/2025 |
| 9.0.28 | 232 | 3/17/2025 |
| 9.0.27 | 261 | 3/16/2025 |
| 9.0.26 | 256 | 3/13/2025 |
| 9.0.25 | 52,120 | 3/9/2025 |
| 9.0.21 | 294 | 3/6/2025 |
| 9.0.20 | 19,528 | 3/6/2025 |