Releases: yv989c/BlazarTech.QueryableValues
Maintenance Release
What's Changed
Full Changelog: v1.3.0...v1.3.1
EF8 Features, Optimizations, and Benchmarks
What's Changed
DateOnly
andTimeOnly
support (#28)- SQL optimization for simple types.
- Updated Benchmarks – QueryableValues is still 🥇.
- Updated docs.
EF8 Release
New Features
New Features
Allow Custom DI Service Provider (Closes #24)
EF allows you to provide a custom DI service provider by using the UseInternalServiceProvider
api. Now you can register the services required by QueryableValues
by using the AddQueryableValuesSqlServer
extension method.
using BlazarTech.QueryableValues;
var internalServiceProviderServices = new ServiceCollection()
.AddEntityFrameworkSqlServer()
.AddQueryableValuesSqlServer();
var internalServiceProvider = internalServiceProviderServices.BuildServiceProvider();
var services = new ServiceCollection();
services.AddDbContext<SomeDbContext>(builder =>
{
builder
.UseInternalServiceProvider(internalServiceProvider)
.UseSqlServer("ConnectionString", options =>
{
options.UseQueryableValues();
});
});
var serviceProvider = services.BuildServiceProvider();
var dbContext = serviceProvider.GetRequiredService<SomeDbContext>();
Enumeration Type Support (Closes #33)
The extension method AsQueryableValues
now has an overload that accepts an enumeration.
enum SomeEnum
{
None,
Value1,
Value2,
Value3
}
...
var values = new[]
{
SomeEnum.None,
SomeEnum.Value3
};
var results = (
from e in dbContext.SomeEntity
join v in dbContext.AsQueryableValues(values) on e.EnumValue equals v
select e.Id
)
.ToList();
That's all for now. ✌️
Ordering Guarantees
In this new release of the QueryableValues library, I've made several improvements, from documentation and code clean-ups to performance enhancements and new features. Here's a detailed rundown of the updates:
New Features
- Order Guarantees and Support for Includes: New features have been added to ensure the order of query results and to extend support for
Include
operations in the presence of a join. This will enable more complex and convenient queries. This was inspired by the following discussion and also closes #31.
Fixes
- JSON serializer .NET Standard 2+ Bug: A bug in the JSON serializer affecting users running the library on .NET Standard 2.0 and later versions has been identified and resolved.
Performance
- XML Query Refactoring: The performance of XML querying has been enhanced through a refactor of the associated parts of the code base. This should result in faster and more efficient XML queries.
Tests
- Updated XML Serializer Test: The XML serializer test has been updated to ensure its continued accuracy in testing the library's functionality.
- Test Cases for Includes and Take/Skip Operations: Additional test cases have been added to cover the "includes" operations and "take/skip" operations, ensuring they function as expected.
Build
- EntityFrameworkCore Dependency: The library now has an open-ended versioning policy for its EntityFrameworkCore dependency. This should provide users with greater flexibility and reduce potential issues related to versioning.
Chores
- Code Clean-up: I've tidied up the codebase, removing unnecessary code and improving its overall cleanliness and maintainability.
Documentation
- I've given the documentation extra attention in this release:
- More TLC: I've put more Tender Loving Care into the docs, making them more detailed, more accurate, and easier to read.
- Addresses OCD Around Line-break: The formatting of the documentation has been improved, especially with regards to line breaks, to enhance readability.
- Some TLC: In addition to adding more information, the overall look and feel of the documentation has been improved.
As always, I appreciate your support and feedback as I continue to improve this library. Please don't hesitate to reach out with any questions or concerns!
🤖 These release notes were mostly generated by ChatGPT (v4).
2 Fast 2 Furious (JSON Support)
Summary
QueryableValues achieves high performance by using parameterized T-SQL queries, which rely on the XML data type support in SQL Server. However, SQL Server 2016 introduced support for JSON, which can provide even better query performance than XML.
This new version of QueryableValues includes support for JSON as an alternative to XML. When JSON support is available, certain scenarios may see a significant performance boost, as evidenced by the benchmarks below.
💡 To take advantage of JSON support, you need to make sure that your SQL Server instance is version 2016 or higher, and that the database's compatibility level is set to 130 or higher.
Configuration
By default, this version of QueryableValues automatically detects whether JSON can be used, and falls back to XML if necessary. However, you can configure this behavior by using the options
parameter when calling UseQueryableValues
during configuration:
...
builder.UseQueryableValues(options =>
{
options.Serialization(SqlServerSerialization.UseJson);
})
...
💡 If your environment supports JSON, use
SqlServerSerialization.UseJson
. Otherwise, useSqlServerSerialization.UseXml
. You can avoid the initial roundtrip that QueryableValues makes to detect JSON support by not usingSqlServerSerialization.Auto
(default). This roundtrip only happens once per connection string and for the life of the process.
Benchmarks
The following benchmarks consist of simple EF Core queries that have a dependency on a random sequence of Int32
, Guid
, and String
values via the Contains
LINQ method. It shows the performance differences between not using and using QueryableValues. In practice, the benefits of using QueryableValues are more dramatic on complex EF Core queries and busy environments.
BenchmarkDotNet System Specs and Configuration
BenchmarkDotNet=v0.13.5, OS=Windows 11 (10.0.22621.1413/22H2/2022Update/SunValley2)
AMD Ryzen 9 6900HS Creator Edition, 1 CPU, 16 logical and 8 physical cores
.NET SDK=7.0.202
[Host] : .NET 6.0.15 (6.0.1523.11507), X64 RyuJIT AVX2
Job-OFVMJD : .NET 6.0.15 (6.0.1523.11507), X64 RyuJIT AVX2
Server=True InvocationCount=200 IterationCount=25
RunStrategy=Monitoring UnrollFactor=1 WarmupCount=1
SQL Server Instance Specs
Microsoft SQL Server 2022 (RTM) - 16.0.1000.6 (X64)
Oct 8 2022 05:58:25
Copyright (C) 2022 Microsoft Corporation
Express Edition (64-bit) on Windows 10 Pro 10.0 <X64> (Build 22621: ) (Hypervisor)
- The SQL Server instance was running in the same system where the benchmarks were executed.
- Shared Memory is the only network protocol that's enabled on this instance.
Query Duration - Without vs. With (XML) vs. With (JSON)
Legend:
- Without: Plain EF.
- With (XML): EF with QueryableValues using the XML serializer.
- With (JSON): EF with QueryableValues using the JSON serializer.
Method | Type | NumberOfValues | Mean | Error | StdDev | Median | Ratio | RatioSD | Gen0 | Gen1 | Gen2 | Allocated | Alloc Ratio |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Without | Int32 | 2 | 824.3 us | 26.03 us | 34.75 us | 808.9 us | 1.00 | 0.00 | - | - | - | 20.26 KB | 1.00 |
WithXml | Int32 | 2 | 508.7 us | 32.46 us | 43.34 us | 504.3 us | 0.62 | 0.04 | - | - | - | 41.37 KB | 2.04 |
WithJson | Int32 | 2 | 431.7 us | 35.52 us | 47.41 us | 446.8 us | 0.52 | 0.05 | - | - | - | 41.5 KB | 2.05 |
Without | Int32 | 8 | 964.8 us | 25.05 us | 33.44 us | 954.6 us | 1.00 | 0.00 | - | - | - | 21.17 KB | 1.00 |
WithXml | Int32 | 8 | 548.2 us | 34.29 us | 45.78 us | 537.0 us | 0.57 | 0.04 | - | - | - | 41.33 KB | 1.95 |
WithJson | Int32 | 8 | 445.1 us | 34.28 us | 45.76 us | 453.6 us | 0.46 | 0.04 | - | - | - | 41.56 KB | 1.96 |
Without | Int32 | 32 | 1,519.3 us | 34.23 us | 45.69 us | 1,494.4 us | 1.00 | 0.00 | - | - | - | 25.45 KB | 1.00 |
WithXml | Int32 | 32 | 687.5 us | 32.29 us | 43.10 us | 664.9 us | 0.45 | 0.03 | - | - | - | 41.52 KB | 1.63 |
WithJson | Int32 | 32 | 448.1 us | 38.22 us | 51.03 us | 425.9 us | 0.30 | 0.04 | - | - | - | 41.61 KB | 1.63 |
Without | Int32 | 128 | 5,470.2 us | 25.34 us | 33.83 us | 5,473.2 us | 1.00 | 0.00 | - | - | - | 41.18 KB | 1.00 |
WithXml | Int32 | 128 | 1,334.4 us | 37.80 us | 50.47 us | 1,316.5 us | 0.24 | 0.01 | - | - | - | 44.02 KB | 1.07 |
WithJson | Int32 | 128 | 498.9 us | 33.69 us | 44.97 us | 498.1 us | 0.09 | 0.01 | - | - | - | 42.53 KB | 1.03 |
Without | Int32 | 512 | 17,572.2 us | 68.50 us | 91.45 us | 17,566.4 us | 1.00 | 0.00 | - | - | - | 105.67 KB | 1.00 |
WithXml | Int32 | 512 | 4,016.2 us | 30.74 us | 41.04 us | 4,014.4 us | 0.23 | 0.00 | - | - | - | 52.18 KB | 0.49 |
WithJson | Int32 | 512 | 685.0 us | 30.40 us | 40.59 us | 661.9 us | 0.04 | 0.00 | - | - | - | 46.37 KB | 0.44 |
Without | Int32 | 2048 | 71,616.8 us | 677.00 us | 903.77 us | 71,227.6 us | 1.00 | 0.00 | - | - | - | 363.17 KB | 1.00 |
WithXml | Int32 | 2048 | 14,045.8 us | 50.55 us | 67.48 us | 14,029.9 us | 0.20 | 0.00 | - | - | - | 84.85 KB | 0.23 |
WithJson | Int32 | 2048 | 1,577.1 us | 32.17 us | 42.95 us | 1,564.8 us | 0.02 | 0.00 | - | - | - | 61.07 KB | 0.17 |
Without | Guid | 2 | 788.9 us | 20.31 us | 27.11 us | 778.1 us | 1.00 | 0.00 | - | - | - | 20.74 KB | 1.00 |
WithXml | Guid | 2 | 487.6 us | 30.51 us | 40.74 us | 487.7 us | 0.62 | 0.04 | - | - | - | 41.23 KB | 1.99 |
WithJson | Guid | 2 | 434.7 us | 33.42 us | 44.61 us | 443.3 us | 0.55 | 0.04 | - | - | - | 41.19 KB | 1.99 |
Without | Guid | 8 | 939.1 us | 29.24 us | 39.04 us | 921.1 us | 1.00 | 0.00 | - | - | - | 23.49 KB | 1.00 |
WithXml | Guid | 8 | 515.1 us | 32.95 us | 43.99 us | 509.2 us | 0.55 | 0.04 | - | - | - | 42.23 KB | 1.80 |
WithJson | Guid | 8 | 450.0 us | 33.55 us | 44.79 us | 461.4 us | 0.48 | 0.04 | - | - | - | 41.98 KB | 1.79 |
Without | Guid | 32 | 1,566.2 us | 43.12 us | 57.56 us | 1,551.3 us | 1.00 | 0.00 | - | - | - | 33.24 KB | 1.00 |
WithXml | Guid | 32 | 607.3 us | 33.01 us | 44.07 us | 587.0 us | 0.39 | 0.03 | - | - | - | 43.58 KB | 1.31 |
WithJson | Guid | 32 | 488.4 us | 32.86 us | 43.87 us | 487.3 us | 0.31 | 0.03 | - | - | - | 43.48 KB | 1.31 |
Without | Guid | 128 | 5,140.0 us | 52.22 us | 69.71 us | 5,138.2 us | 1.00 | 0.00 | - | - | - | 74.11 KB | 1.00 |
WithXml | Guid | 128 | 987.8 us | 37.30 us | 49.79 us | 965.0 us | 0.19 | 0.01 | - | - | - | 51.97 KB | 0.70 |
... |
Maintenance Release
- Added the
UseDeferredEnumeration
option that allows you to disable deferred enumeration. By disabling this feature you will be able to use theToQueryString
method provided by EF 5 onwards. If possible, I recommend leaving this feature enabled (default). For details please refer to theUseDeferredEnumeration
method documentation.
Configuration example:
builder.UseQueryableValues(options =>
{
// Disables deferred enumeration.
options.UseDeferredEnumeration(false);
})
Provides a workaround for #25 .
EF Core 7 Support (Release)
Merge pull request #21 from yv989c/develop Support for the release version of EF Core 7
Let's Enhance
Highlights
- CI/CD pipeline improvements.
- Tests now target multiple runtimes.
- Docs now mention QueryableValues
EF6 Edition
. - New feature!
IQueryableValuesEnabledDbContext
✌
EF Core 7 support
- New package aligned with the major version of EF 7 Core (in preview).
- Minor changes around docs.
That's it.