FractalDataWorks.Commands.Data
0.6.0-rc.1
dotnet add package FractalDataWorks.Commands.Data --version 0.6.0-rc.1
NuGet\Install-Package FractalDataWorks.Commands.Data -Version 0.6.0-rc.1
<PackageReference Include="FractalDataWorks.Commands.Data" Version="0.6.0-rc.1" />
<PackageVersion Include="FractalDataWorks.Commands.Data" Version="0.6.0-rc.1" />
<PackageReference Include="FractalDataWorks.Commands.Data" />
paket add FractalDataWorks.Commands.Data --version 0.6.0-rc.1
#r "nuget: FractalDataWorks.Commands.Data, 0.6.0-rc.1"
#:package FractalDataWorks.Commands.Data@0.6.0-rc.1
#addin nuget:?package=FractalDataWorks.Commands.Data&version=0.6.0-rc.1&prerelease
#tool nuget:?package=FractalDataWorks.Commands.Data&version=0.6.0-rc.1&prerelease
FractalDataWorks.Commands.Data
Data command implementations for the FractalDataWorks framework, providing a type-safe API for data operations across different backends.
Overview
This package provides concrete implementations of data commands that work with SQL databases, REST APIs, file systems, and other data sources. Commands are translated by backend-specific translators to native operations.
Installation
<PackageReference Include="FractalDataWorks.Commands.Data" Version="1.0.0" />
Architecture
Application Code
|
DataCommands (Universal)
|
Translators (Backend-Specific)
|
DataGateway
|
Connections (Protocol)
|
Data Sources
Projects
| Project | Purpose |
|---|---|
FractalDataWorks.Commands.Data.Abstractions |
Interfaces and base classes |
FractalDataWorks.Commands.Data |
Concrete command implementations |
FractalDataWorks.Commands.Data.Extensions |
Builder methods for commands |
Command Types
From QueryCommand.cs:59-106:
[TypeOption(typeof(DataCommands), "Query")]
public sealed class QueryCommand<T> : DataCommandBase<IEnumerable<T>>, IQueryCommand
{
public QueryCommand(string containerName)
: base("Query", containerName)
{
}
public IFilterExpression? Filter { get; init; }
public IProjectionExpression? Projection { get; init; }
public IOrderingExpression? Ordering { get; init; }
public IPagingExpression? Paging { get; init; }
public IAggregationExpression? Aggregation { get; init; }
public IReadOnlyList<IJoinExpression> Joins { get; init; } = [];
}
Available commands:
QueryCommand<T>- Retrieve data (SELECT)InsertCommand<T>- Add new data (INSERT)UpdateCommand<T>- Modify existing data (UPDATE)DeleteCommand- Remove data (DELETE)BulkInsertCommand<T>- Bulk insert operations
Usage
Query with Filter
Filters use a composite pattern with FilterCondition (leaf) and FilterGroup (composite).
From FilterCondition.cs:26-43:
public sealed record FilterCondition : IFilterCondition, IFilterNode
{
public required string PropertyName { get; init; }
public required IFilterOperator Operator { get; init; }
public object? Value { get; init; }
}
From FilterExpression.cs:51-57:
public sealed class FilterExpression : IFilterExpression
{
public IFilterNode? Root { get; init; }
}
Example - simple filter:
var command = new QueryCommand<Customer>("Customers")
{
Filter = new FilterExpression
{
Root = new FilterCondition
{
PropertyName = nameof(Customer.IsActive),
Operator = FilterOperators.Equal,
Value = true
}
}
};
Example - complex filter with grouping (from FilterGroup.cs:23-34):
// (Name LIKE '%Acme%' OR Name LIKE '%Corp%') AND IsActive = true
var command = new QueryCommand<Customer>("Customers")
{
Filter = new FilterExpression
{
Root = new FilterGroup
{
Operator = LogicalOperator.And,
Nodes =
[
new FilterGroup
{
Operator = LogicalOperator.Or,
Nodes =
[
new FilterCondition
{
PropertyName = "Name",
Operator = FilterOperators.Contains,
Value = "Acme"
},
new FilterCondition
{
PropertyName = "Name",
Operator = FilterOperators.Contains,
Value = "Corp"
}
]
},
new FilterCondition
{
PropertyName = "IsActive",
Operator = FilterOperators.Equal,
Value = true
}
]
}
}
};
Query with Ordering and Paging
From OrderingExpression.cs:9-16 and PagingExpression.cs:8-20:
var command = new QueryCommand<Customer>("Customers")
{
Ordering = new OrderingExpression
{
OrderedFields =
[
new OrderedField
{
PropertyName = "Name",
Direction = SortDirections.Ascending
}
]
},
Paging = new PagingExpression
{
Skip = 0,
Take = 50
}
};
Insert Command
From InsertCommand.cs:35-47:
[TypeOption(typeof(DataCommands), "Insert")]
public sealed class InsertCommand<T> : DataCommandBase<int, T>
{
public InsertCommand(string containerName, T data)
: base("Insert", containerName, data)
{
}
}
Usage:
var customer = new Customer
{
Name = "Acme Corp",
Email = "contact@acme.com",
IsActive = true
};
var command = new InsertCommand<Customer>("Customers", customer);
Update Command
From UpdateCommand.cs:47-65:
[TypeOption(typeof(DataCommands), "Update")]
public sealed class UpdateCommand<T> : DataCommandBase<int, T>, IFilterableCommand
{
public UpdateCommand(string containerName, T data)
: base("Update", containerName, data)
{
}
public IFilterExpression? Filter { get; init; }
}
Usage:
var customer = new Customer { Id = 123, Name = "Acme Corp Updated", IsActive = false };
var command = new UpdateCommand<Customer>("Customers", customer)
{
Filter = new FilterExpression
{
Root = new FilterCondition
{
PropertyName = "Id",
Operator = FilterOperators.Equal,
Value = 123
}
}
};
Delete Command
From DeleteCommand.cs:45-62:
[TypeOption(typeof(DataCommands), "Delete")]
public sealed class DeleteCommand : DataCommandBase<int>, IFilterableCommand
{
public DeleteCommand(string containerName)
: base("Delete", containerName)
{
}
public IFilterExpression? Filter { get; init; }
}
Usage:
var command = new DeleteCommand("Customers")
{
Filter = new FilterExpression
{
Root = new FilterCondition
{
PropertyName = "IsActive",
Operator = FilterOperators.Equal,
Value = false
}
}
};
Filter Operators
From FilterOperators.cs:40-50, the TypeCollection provides static properties for each operator:
| Operator | SQL | OData |
|---|---|---|
FilterOperators.Equal |
= |
eq |
FilterOperators.NotEqual |
<> |
ne |
FilterOperators.GreaterThan |
> |
gt |
FilterOperators.GreaterThanOrEqual |
>= |
ge |
FilterOperators.LessThan |
< |
lt |
FilterOperators.LessThanOrEqual |
<= |
le |
FilterOperators.Contains |
LIKE |
contains |
FilterOperators.StartsWith |
LIKE |
startswith |
FilterOperators.EndsWith |
LIKE |
endswith |
FilterOperators.In |
IN |
in |
FilterOperators.IsNull |
IS NULL |
eq null |
FilterOperators.IsNotNull |
IS NOT NULL |
ne null |
Execution via DataGateway
Commands are executed through the IDataGateway interface, which routes commands to the appropriate connection based on ConnectionName.
From IDataGateway.cs:14-24:
public interface IDataGateway
{
Task<IGenericResult<T>> Execute<T>(IDataCommand command, CancellationToken cancellationToken = default);
}
Usage:
var command = new QueryCommand<Customer>("Customers")
{
Filter = new FilterExpression
{
Root = new FilterCondition
{
PropertyName = nameof(Customer.IsActive),
Operator = FilterOperators.Equal,
Value = true
}
}
};
var result = await gateway.Execute<IEnumerable<Customer>>(command, cancellationToken);
if (result.IsSuccess)
{
foreach (var customer in result.Value)
{
Console.WriteLine(customer.Name);
}
}
else
{
Console.WriteLine($"Error: {result.Error}");
}
Framework Patterns
Railway-Oriented Programming
All command execution returns IGenericResult<T>, enabling explicit error handling without exceptions.
TypeCollections
Commands and operators use TypeCollections instead of enums, providing:
- Compile-time type safety
- Cross-assembly extensibility
- No switch statements needed
- Each operator knows its SQL/OData representations
From EqualOperator.cs:10-48:
[TypeOption(typeof(FilterOperators), "Equal")]
public sealed class EqualOperator : FilterOperatorBase
{
public EqualOperator()
: base(
id: 1,
name: "Equal",
sqlOperator: "=",
odataOperator: "eq",
requiresValue: true)
{
}
public override string FormatODataValue(object? value)
{
// Operator knows its own formatting
}
}
Related Packages
- FractalDataWorks.Commands.Data.Abstractions - Interfaces and base classes
- FractalDataWorks.Commands.Data.Extensions - Builder methods
- FractalDataWorks.Data - Filter operators and expressions
- FractalDataWorks.Services.Data - DataGateway implementation
Next Steps
- See FractalDataWorks.Data.MsSql for SQL Server translator implementation
- See FractalDataWorks.Data.Rest for REST API translator implementation
- See the wiki for architecture details and patterns
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- FractalDataWorks.Collections (>= 0.6.0-rc.1)
- FractalDataWorks.Commands.Data.Abstractions (>= 0.6.0-rc.1)
- FractalDataWorks.Data (>= 0.6.0-rc.1)
- FractalDataWorks.Messages (>= 0.6.0-rc.1)
- FractalDataWorks.Results (>= 0.6.0-rc.1)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.1)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on FractalDataWorks.Commands.Data:
| Package | Downloads |
|---|---|
|
FractalDataWorks.Commands.Data.Extensions
Development tools and utilities for the FractalDataWorks ecosystem. Build: |
|
|
FractalDataWorks.Calculations.Aggregations
Development tools and utilities for the FractalDataWorks ecosystem. Build: |
|
|
FractalDataWorks.Configuration.MsSql
Development tools and utilities for the FractalDataWorks ecosystem. Build: |
GitHub repositories
This package is not used by any popular GitHub repositories.