FluentDynamics.QueryBuilder
1.0.4
See the version list below for details.
dotnet add package FluentDynamics.QueryBuilder --version 1.0.4
NuGet\Install-Package FluentDynamics.QueryBuilder -Version 1.0.4
<PackageReference Include="FluentDynamics.QueryBuilder" Version="1.0.4" />
<PackageVersion Include="FluentDynamics.QueryBuilder" Version="1.0.4" />
<PackageReference Include="FluentDynamics.QueryBuilder" />
paket add FluentDynamics.QueryBuilder --version 1.0.4
#r "nuget: FluentDynamics.QueryBuilder, 1.0.4"
#:package FluentDynamics.QueryBuilder@1.0.4
#addin nuget:?package=FluentDynamics.QueryBuilder&version=1.0.4
#tool nuget:?package=FluentDynamics.QueryBuilder&version=1.0.4
FluentDynamics QueryBuilder
FluentDynamics QueryBuilder is a fluent, chainable API for building and executing Dynamics 365/Dataverse queries. It simplifies the process of creating complex QueryExpressions with a more intuitive and readable syntax.
Features
- 🔄 Fluent API - Chainable, intuitive query building
- 🔍 Type-safe - Strong typing for Dynamics 365 operations
- 🚀 Async Support - Full support for async/await patterns
- 📊 LINQ-like Operations - Familiar extension methods for query results
- 📑 Pagination - Built-in support for handling paged results
- 🔗 Complex Joins - Easily create and configure link-entity operations
- 🧩 Extensible - Clean architecture for extending functionality
- 🛠 FetchXML Conversion - Convert queries to FetchXML easily
- 🧮 Distinct, NoLock, QueryHint, ForceSeek - Advanced query options
Installation
Install via NuGet Package Manager:
Install-Package FluentDynamics.QueryBuilder
Or via .NET CLI:
dotnet add package FluentDynamics.QueryBuilder
Basic Usage
using FluentDynamics.QueryBuilder;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
// Create a simple query
var query = Query.For("account")
.Select("name", "accountnumber", "telephone1")
.Where(f => f
.Condition("statecode", ConditionOperator.Equal, 0)
)
.OrderBy("name");
// Execute the query
EntityCollection results = query.RetrieveMultiple(organizationService);
// Use extension methods on results
var accounts = results.ToList();
Advanced Examples
Complex Filtering (Nested AND/OR)
var query = Query.For("contact")
.Select("firstname", "lastname", "emailaddress1")
.Where(f => f
.Condition("statecode", ConditionOperator.Equal, 0)
.And(fa => fa
.Condition("createdon", ConditionOperator.LastXDays, 30)
.Condition("emailaddress1", ConditionOperator.NotNull)
)
.Or(fo => fo
.Condition("parentcustomerid", ConditionOperator.Equal, accountId)
.Condition("address1_city", ConditionOperator.Equal, "Seattle")
)
)
.OrderBy("lastname")
.OrderBy("firstname");
Joining Entities (Link Entities)
var query = Query.For("opportunity")
.Select("name", "estimatedvalue", "closeprobability")
.Where(f => f
.Condition("statecode", ConditionOperator.Equal, 0)
)
.Link("account", "customerid", "accountid", JoinOperator.Inner, link => {
link.Select("name", "accountnumber")
.As("account")
.Where(f => f
.Condition("statecode", ConditionOperator.Equal, 0)
);
})
.Link("contact", "customerid", "contactid", JoinOperator.LeftOuter, link => {
link.Select("fullname", "emailaddress1")
.As("contact");
});
Pagination & Async
// Get a specific page
var page2 = query.RetrieveMultiple(service, pageNumber: 2, pageSize: 50);
// Retrieve all pages automatically
var allResults = query.RetrieveMultipleAllPages(service);
// Using async version
var results = await query.RetrieveMultipleAsync(service);
// Async with pagination
var pageResults = await query.RetrieveMultipleAsync(service, pageNumber: 2, pageSize: 50);
// Async all pages
var allAsyncResults = await query.RetrieveMultipleAllPagesAsync(service);
FetchXML Conversion
// Convert QueryExpression to FetchXML
var fetchXml = query.ToFetchExpression(service);
Working with Results
// Convert to list
var entities = results.ToList();
// Filter results
var filteredEntities = results.Where(e => e.Contains("emailaddress1"));
// Project to new form
var names = results.Select(e => e.GetAttributeValue<string>("name"));
// Get first matching entity
var matchingContact = results.FirstOrDefault(e =>
e.GetAttributeValue<string>("emailaddress1")?.Contains("example.com") == true);
// Safe attribute access
string name = entity.TryGet<string>("name", "Default Name");
API Reference
Query
Entry point for building queries:
Query.For(entityName)
- Creates a new query for the specified entity
QueryExpressionBuilder
Methods for configuring the main query:
Select(params string[] attributes)
- Specifies columns to includeSelectAll()
- Includes all columnsWhere(Action<FilterBuilder> filterConfig)
- Adds a filter group using fluent configurationOrderBy(attribute, [orderType])
- Adds a sort orderLink(toEntity, fromAttribute, toAttribute, joinType, Action<LinkEntityBuilder> linkBuilder)
- Adds a joinTop(count)
- Limits the number of recordsDistinct()
- Returns only distinct recordsNoLock()
- Uses NOLOCK hintQueryHint(hint)
- Adds a query hintForceSeek(indexName)
- Forces using a specific index
Execution Methods
RetrieveMultiple(service)
- Executes the query and returns resultsRetrieveMultiple(service, pageNumber, pageSize)
- Executes with paginationRetrieveMultipleAllPages(service)
- Retrieves all pages synchronouslyRetrieveMultipleAsync(service, CancellationToken cancellationToken = default)
- Async versionRetrieveMultipleAsync(service, pageNumber, pageSize, CancellationToken cancellationToken = default)
- Async with paginationRetrieveMultipleAllPagesAsync(service, CancellationToken cancellationToken = default)
- Async all pagesToQueryExpression()
- Converts to QueryExpressionToFetchExpression(service)
- Converts to FetchXML
FilterBuilder
Builds complex filter logic:
Condition(attribute, operator, value)
- Adds a conditionAnd(Action<FilterBuilder> nested)
- Adds a nested AND filter groupOr(Action<FilterBuilder> nested)
- Adds a nested OR filter groupToExpression()
- Returns the built FilterExpression
LinkEntityBuilder
Configures join/link entities:
Select(params string[] attributes)
- Specifies columns to include from the linked entitySelectAll()
- Includes all columns from the linked entityAs(alias)
- Sets an alias for the linked entityOrderBy(attribute, [orderType])
- Adds sort order to the linked entityWhere(Action<FilterBuilder> filterConfig)
- Configures link entity filters using a FilterBuilderLink(toEntity, fromAttribute, toAttribute, joinType, Action<LinkEntityBuilder> linkBuilder)
- Adds a nested link-entity (join)
Extension Methods (LINQ-like)
ToList()
/ToArray()
- Convert results to collection typesFirstOrDefault(predicate)
- Returns first matching entitySingleOrDefault(predicate)
- Returns single matching entityWhere(predicate)
- Filters entitiesSelect(selector)
- Projects entities to new formTryGet<T>(attributeName, defaultValue)
- Safely gets attribute valueClone()
- Deep clone of a query builder instance
Module Coverage
Module | Line | Branch | Method |
---|---|---|---|
FluentDynamics.QueryBuilder | 76.21% | 61.36% | 61.11% |
Overall Coverage
Metric | Line | Branch | Method |
---|---|---|---|
Total | 76.21% | 61.36% | 61.11% |
Average | 76.2% | 61.36% | 61.11% |
Test Summary
- Total Tests: 40
- Failed: 0
- Succeeded: 40
- Skipped: 0
- Duration: 2.5s
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Microsoft.PowerPlatform.Dataverse.Client (>= 1.2.10)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.