FractalDataWorks.Data 0.4.0-preview.6

This is a prerelease version of FractalDataWorks.Data.
The owner has unlisted this package. This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet add package FractalDataWorks.Data --version 0.4.0-preview.6
                    
NuGet\Install-Package FractalDataWorks.Data -Version 0.4.0-preview.6
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="FractalDataWorks.Data" Version="0.4.0-preview.6" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="FractalDataWorks.Data" Version="0.4.0-preview.6" />
                    
Directory.Packages.props
<PackageReference Include="FractalDataWorks.Data" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add FractalDataWorks.Data --version 0.4.0-preview.6
                    
#r "nuget: FractalDataWorks.Data, 0.4.0-preview.6"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package FractalDataWorks.Data@0.4.0-preview.6
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=FractalDataWorks.Data&version=0.4.0-preview.6&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=FractalDataWorks.Data&version=0.4.0-preview.6&prerelease
                    
Install as a Cake Tool

FractalDataWorks.Data

Cross-cutting data domain types including TypeCollections for filter operators, sort directions, join types, and expression types.

Overview

This package provides common data types used across the FractalDataWorks framework for building data queries. It implements TypeCollections that replace enums with extensible, type-safe alternatives that know their own SQL and OData representations.

Installation

<PackageReference Include="FractalDataWorks.Data" Version="1.0.0" />

Key Types

TypeCollections

  • FilterOperators - Operators for filter expressions (Equal, NotEqual, Contains, GreaterThan, etc.)
  • SortDirections - Sort directions for ORDER BY clauses (Ascending, Descending)
  • JoinTypes - Join types for data operations (Inner, Left, Right, Full, Cross, None)
  • ContainerTypes - Container type definitions
  • PathTypes - Data path type definitions

Expression Types

  • FilterExpression - Hierarchical WHERE clause representation
  • FilterCondition - Single filter condition (property, operator, value)
  • FilterGroup - Group of filter nodes with logical operator (AND/OR)
  • OrderingExpression - ORDER BY clause representation
  • OrderedField - Single ordered field with direction
  • PagingExpression - SKIP/TAKE pagination
  • JoinExpression - JOIN clause representation
  • ProjectionExpression - SELECT clause representation
  • AggregationExpression - Aggregation function representation

Usage

FilterOperators TypeCollection

From FilterOperators.cs:40-50:

[TypeCollection(typeof(FilterOperatorBase), typeof(IFilterOperator), typeof(FilterOperators))]
[ExcludeFromCodeCoverage]
public abstract partial class FilterOperators : TypeCollectionBase<FilterOperatorBase, IFilterOperator>
{
    // Source generator will create:
    // - Static constructor
    // - Static properties for each [TypeOption] operator
    // - All() method
    // - GetByName() method
    // - GetById() method
}

Access operators via generated static properties or lookup methods:

From Reference Solution Program.cs:28-47:

// Access operators via static properties (type-safe, no magic strings)
Console.WriteLine("   Direct property access (generated static properties):");
Console.WriteLine($"   - FilterOperators.Equal.SqlOperator = \"{FilterOperators.Equal.SqlOperator}\"");
Console.WriteLine($"   - FilterOperators.Contains.SqlOperator = \"{FilterOperators.Contains.SqlOperator}\"");
Console.WriteLine($"   - FilterOperators.GreaterThan.SqlOperator = \"{FilterOperators.GreaterThan.SqlOperator}\"");
Console.WriteLine($"   - FilterOperators.IsNull.SqlOperator = \"{FilterOperators.IsNull.SqlOperator}\"");

// List all operators
Console.WriteLine("   All filter operators:");
foreach (var op in FilterOperators.All())
{
    Console.WriteLine($"   - {op.Name}: SQL=\"{op.SqlOperator}\", OData=\"{op.ODataOperator}\", RequiresValue={op.RequiresValue}");
}

// ByName lookup (O(1)) - useful for deserialization from config/database
Console.WriteLine("   ByName lookup (O(1) via FrozenDictionary):");
var opFromConfig = FilterOperators.ByName("NotEqual");
Console.WriteLine($"   - FilterOperators.ByName(\"NotEqual\").SqlOperator = \"{opFromConfig.SqlOperator}\"");

FilterCondition

From FilterCondition.cs:26-43:

public sealed record FilterCondition : IFilterCondition, IFilterNode
{
    /// <summary>
    /// Gets the property name to filter on.
    /// </summary>
    public required string PropertyName { get; init; }

    /// <summary>
    /// Gets the filter operator.
    /// This is a FilterOperatorBase (TypeCollection), not an enum!
    /// </summary>
    public required IFilterOperator Operator { get; init; }

    /// <summary>
    /// Gets the value to compare against (null for IS NULL / IS NOT NULL operators).
    /// </summary>
    public object? Value { get; init; }
}

Building filter conditions:

From Reference Solution Program.cs:66-90:

// Simple equality condition
var nameFilter = new FilterCondition
{
    PropertyName = "CustomerName",
    Operator = FilterOperators.Equal,
    Value = "Acme Corp"
};
Console.WriteLine($"   Simple: [{nameFilter.PropertyName}] {nameFilter.Operator.SqlOperator} @{nameFilter.PropertyName}");

// Contains (LIKE) condition - operator knows its own SQL!
var searchFilter = new FilterCondition
{
    PropertyName = "Description",
    Operator = FilterOperators.Contains,
    Value = "widget"
};
Console.WriteLine($"   Contains: [{searchFilter.PropertyName}] {searchFilter.Operator.SqlOperator} @{searchFilter.PropertyName}");

// Null check (no value needed)
var nullCheck = new FilterCondition
{
    PropertyName = "DeletedAt",
    Operator = FilterOperators.IsNull
    // No Value - IsNull doesn't need one (RequiresValue = false)
};
Console.WriteLine($"   NullCheck: [{nullCheck.PropertyName}] {nullCheck.Operator.SqlOperator}");

SortDirections TypeCollection

From SortDirections.cs:7-15:

/// <summary>
/// Collection of sort directions for data queries.
/// Generated by TypeCollectionGenerator with high-performance lookups.
/// </summary>
[ExcludeFromCodeCoverage]
[TypeCollection(typeof(SortDirectionBase), typeof(ISortDirection), typeof(SortDirections))]
public abstract partial class SortDirections : TypeCollectionBase<SortDirectionBase, ISortDirection>
{
}

From Reference Solution Program.cs:53-58:

Console.WriteLine("2. SortDirections TypeCollection:");
foreach (var direction in SortDirections.All())
{
    Console.WriteLine($"   - {direction.Name} (SqlKeyword: \"{direction.SqlKeyword}\")");
}

OrderedField and OrderingExpression

From OrderedField.cs:6-18:

public sealed record OrderedField : IOrderedField
{
    /// <summary>
    /// Gets the property name to order by.
    /// </summary>
    public required string PropertyName { get; init; }

    /// <summary>
    /// Gets the sort direction.
    /// This is a SortDirection TypeCollection, not a traditional enum!
    /// </summary>
    public required ISortDirection Direction { get; init; }
}

From Reference Solution Program.cs:152-162:

Ordering = new OrderingExpression
{
    OrderedFields =
    [
        new OrderedField
        {
            PropertyName = "CustomerName",
            Direction = SortDirections.Ascending
        }
    ]
},

FilterExpression

From FilterExpression.cs:51-57:

public sealed class FilterExpression : IFilterExpression
{
    /// <summary>
    /// Gets or sets the root filter node.
    /// </summary>
    public IFilterNode? Root { get; init; }
}

From Reference Solution Program.cs:141-151:

var directQuery = new QueryCommand<CustomerDto>("dbo.Customers")
{
    Filter = new FilterExpression
    {
        Root = new FilterCondition
        {
            PropertyName = "IsActive",
            Operator = FilterOperators.Equal,
            Value = true
        }
    },

ByName Lookup for Configuration

When operators are stored in configuration or databases, use ByName lookup:

From ConfigurationLoader.cs:191-202:

var headerQuery = new QueryCommand<ConfigurationHeaderEntity>("Configuration")
{
    Filter = new FilterExpression
    {
        Root = new FilterCondition
        {
            PropertyName = "ServiceCategory",
            Operator = FilterOperators.ByName("Equal"),
            Value = "DataStore"
        }
    }
};

FilterOperator Implementations

The package includes these built-in filter operators:

Operator SQL OData RequiresValue
Equal = eq true
NotEqual <> ne true
GreaterThan > gt true
GreaterThanOrEqual >= ge true
LessThan < lt true
LessThanOrEqual <= le true
Contains LIKE contains true
StartsWith LIKE startswith true
EndsWith LIKE endswith true
In IN in true
IsNull IS NULL eq null false
IsNotNull IS NOT NULL ne null false

Best Practices

  1. Use static properties when the operator is known at compile time - see Reference Solution Program.cs:69 for usage of FilterOperators.Equal.

  2. Use ByName lookup when operators come from configuration - see ConfigurationLoader.cs:198 for FilterOperators.ByName("Equal").

  3. Check RequiresValue before setting Value - operators like IsNull and IsNotNull do not require values.

From MsSqlDataCommandTranslatorBase.cs:153-164:

var columnName = $"[{condition.PropertyName}]";
var sql = $"{columnName} {condition.Operator.SqlOperator}";

if (condition.Operator.RequiresValue)
{
    var paramName = $"{context.ParameterPrefix}p{context.ParameterCounter++}";
    sql += $" {paramName}";

    // ZERO SQL INJECTION: Value goes into parameter, NOT concatenated into SQL
    var parameter = new SqlParameter(paramName, condition.Value ?? DBNull.Value);
    context.Command.Parameters.Add(parameter);
}
  1. Leverage operator knowledge - operators know their own SQL/OData representations, eliminating switch statements. See FilterOperatorBase.SqlOperator and FilterOperatorBase.ODataOperator properties.

Next Steps

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on FractalDataWorks.Data:

Package Downloads
FractalDataWorks.Commands.Data

Development tools and utilities for the FractalDataWorks ecosystem. Build:

FractalDataWorks.Commands.Data.Extensions

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.

Version Downloads Last Updated
Loading failed