A lightweight, extensible Entity Framework Core provider for translating LINQ queries into Kusto Query Language (KQL) AKA Azure Data Explorer (ADX).
While I primarily built this to integrate with ASP.NET Core OData (v8+) for analytical workloads, it can be used standalone for any LINQ-to-KQL translation needs.
- 1. Installation
- 2. Getting Started
- 3. Project Goals
- 4. Read Capabilities
- 5. Write Capabilities
- 6. Changelog
- 7. Contributing
- 8. License
- 9. Disclaimer
Install the package from NuGet:
dotnet add package EFCore.KustoOr via csproj:
<ProjectReference Include="src/EFCore.Kusto/EFCore.Kusto.csproj" />-
Register your DbContext with the Kusto provider and pick an authentication option:
builder.Services.AddDbContext<PropertyContext>((sp, options) => { options.UseKusto( clusterUrl: "https://<cluster>.kusto.windows.net", database: "<database>", kusto => kusto.UseManagedIdentity()); });
- Use
UseManagedIdentity(clientId)for a user-assigned identity, or omit the client id for system-assigned identities. - Use
UseApplicationAuthentication(tenantId, clientId, clientSecret)for app registrations. - Use
UseTokenCredential(credential)to supply anyTokenCredential(e.g., one registered viaAddKustoManagedIdentityCredentialorAddKustoApplicationRegistration). - If no authentication option is configured, the provider falls back to
DefaultAzureCredentialwhen executing queries.
- Use
-
Optional: register shared credentials so they can be reused when building
DbContextoptions:builder.Services.AddKustoManagedIdentityCredential(clientId: "<client-id>"); // or builder.Services.AddKustoApplicationRegistration( tenantId: "<tenant-id>", clientId: "<client-id>", clientSecret: "<client-secret>");
These helpers register a singleton
TokenCredentialyou can inject when callingUseTokenCredentialinsideAddDbContext.
- Provide a reliable LINQ-to-KQL translation layer.
- Integrate cleanly with ASP.NET Core OData (v8+).
- Offer predictable, debuggable SQL generation.
- Ensure correctness and performance for high‑volume analytical datasets.
- Remain lightweight with minimal runtime overhead.
This provider currently supports:
WherefiltersSelectprojections- Ordering (
OrderBy,ThenBy) - Pagination (
Skip,Take) - Basic join translation used by OData
$expand - Counts as used by OData
$count
EFCore.Kusto works well with:
$filter$select$orderby$count$skip,$top$expand(entity relationships)
If specific OData query shapes cause issues, they can be addressed case‑by‑case. Community reports are welcome.
EFCore.Kusto supports data modification using Kusto-native control commands.
- Insert (
Add,AddRange) via.ingest - Update (
Update) via.update table - Delete (
Remove,RemoveRange) via.delete table
- Commands are batched per entity type and target table
- Read and write operations are never mixed in the same batch
- Each batch is executed as a single Kusto command
Note: Transactional guarantees and concurrency semantics are constrained by Kusto’s execution model.
See CHANGELOG.md for a detailed version history.
Contributions are welcome.
If you encounter a translation issue, please include:
- The LINQ expression (or OData URL if applicable).
- The expected KQL.
- The generated KQL (if available).
This helps isolate translation gaps quickly.
MIT License – simple, permissive, widely accepted.
EFCore.Kusto is free for commercial and open‑source use.
While this provider is functional and under active development, it is not yet battle-tested in production environments.
If you encounter unexpected behavior, open an issue — the goal is full reliability for production workloads.