diff --git a/README.md b/README.md index 2186a15..695d4c3 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,6 @@ For a detailed explanation of the problem solved by QueryableValues, please cont > πŸ’‘ Still on Entity Framework 6 (non-core)? Then [QueryableValues `EF6 Edition`](https://github.com/yv989c/BlazarTech.QueryableValues.EF6) is what you need. -## When Should You Use It? -The `AsQueryableValues` extension method is intended for queries that are dependent upon a *non-constant* sequence of external values. It provides a solution to the following [EF Core issue](https://github.com/dotnet/efcore/issues/13617) and enables other currently unsupported scenarios; like the ability to efficiently create joins with in-memory data. - ## Your Support is Appreciated! If you feel that this solution has provided you some value, please consider [buying me a β˜•][BuyMeACoffee]. @@ -92,7 +89,7 @@ Below are a few examples composing a query using the values provided by an [IEnu ### Simple Type Examples -> πŸ’‘ Supports [Byte], [Int16], [Int32], [Int64], [Decimal], [Single], [Double], [DateTime], [DateTimeOffset], [Guid], [Char], [String], and [Enum]. +> πŸ’‘ Supports [Byte], [Int16], [Int32], [Int64], [Decimal], [Single], [Double], [DateTime], [DateTimeOffset], [DateOnly], [TimeOnly], [Guid], [Char], [String], and [Enum]. Using the [Contains][ContainsQueryable] LINQ method: @@ -197,24 +194,24 @@ The following [benchmarks] consist of simple EF Core queries that have a depende ### Benchmarked Libraries | Package | Version | | ------- |:-------:| -| Microsoft.EntityFrameworkCore.SqlServer | 7.0.4 | -| BlazarTech.QueryableValues.SqlServer | 7.2.0 | +| Microsoft.EntityFrameworkCore.SqlServer | 8.0.0 | +| BlazarTech.QueryableValues.SqlServer | 8.1.0 | ### BenchmarkDotNet System Specs and Configuration ``` -BenchmarkDotNet=v0.13.5, OS=Windows 11 (10.0.22621.1413/22H2/2022Update/SunValley2) +BenchmarkDotNet v0.13.10, Windows 11 (10.0.22621.2715/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 +.NET SDK 8.0.100 + [Host] : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2 + Job-EBAAJF : .NET 8.0.0 (8.0.23.53103), 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 +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 (Build 22621: ) (Hypervisor) ``` @@ -233,82 +230,86 @@ Express Edition (64-bit) on Windows 10 Pro 10.0 (Build 22621: ) (Hyperviso
-| 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 | -| WithJson | Guid | 128 | 665.9 us | 38.37 us | 51.23 us | 636.8 us | 0.13 | 0.01 | - | - | - | 51.12 KB | 0.69 | -| | | | | | | | | | | | | | | -| Without | Guid | 512 | 16,031.0 us | 74.08 us | 98.89 us | 16,023.7 us | 1.00 | 0.00 | - | - | - | 219.5 KB | 1.00 | -| WithXml | Guid | 512 | 2,528.8 us | 38.80 us | 51.79 us | 2,517.7 us | 0.16 | 0.00 | - | - | - | 84.36 KB | 0.38 | -| WithJson | Guid | 512 | 1,368.8 us | 22.42 us | 29.93 us | 1,355.1 us | 0.09 | 0.00 | - | - | - | 80.08 KB | 0.36 | -| | | | | | | | | | | | | | | -| Without | Guid | 2048 | 71,956.6 us | 688.35 us | 918.93 us | 72,148.6 us | 1.00 | 0.00 | - | - | - | 801.13 KB | 1.00 | -| WithXml | Guid | 2048 | 9,399.9 us | 76.33 us | 101.90 us | 9,359.8 us | 0.13 | 0.00 | 5.0000 | 5.0000 | 5.0000 | 213.42 KB | 0.27 | -| WithJson | Guid | 2048 | 4,463.6 us | 36.90 us | 49.26 us | 4,442.6 us | 0.06 | 0.00 | - | - | - | 197.4 KB | 0.25 | -| | | | | | | | | | | | | | | -| Without | String | 2 | 858.7 us | 23.34 us | 31.16 us | 846.2 us | 1.00 | 0.00 | - | - | - | 21.44 KB | 1.00 | -| WithXml | String | 2 | 637.4 us | 35.57 us | 47.48 us | 626.0 us | 0.74 | 0.04 | - | - | - | 55.52 KB | 2.59 | -| WithJson | String | 2 | 534.5 us | 30.81 us | 41.13 us | 528.7 us | 0.62 | 0.03 | - | - | - | 42.83 KB | 2.00 | -| | | | | | | | | | | | | | | -| Without | String | 8 | 1,028.9 us | 24.07 us | 32.13 us | 1,015.2 us | 1.00 | 0.00 | - | - | - | 25.55 KB | 1.00 | -| WithXml | String | 8 | 737.8 us | 44.23 us | 59.05 us | 727.5 us | 0.72 | 0.04 | - | - | - | 56.98 KB | 2.23 | -| WithJson | String | 8 | 641.8 us | 34.63 us | 46.23 us | 640.1 us | 0.62 | 0.04 | - | - | - | 43.64 KB | 1.71 | -| | | | | | | | | | | | | | | -| Without | String | 32 | 1,692.5 us | 23.43 us | 31.27 us | 1,684.7 us | 1.00 | 0.00 | - | - | - | 41.84 KB | 1.00 | -| WithXml | String | 32 | 1,016.7 us | 56.75 us | 75.76 us | 976.6 us | 0.60 | 0.04 | - | - | - | 60.35 KB | 1.44 | -| WithJson | String | 32 | 871.5 us | 39.02 us | 52.10 us | 843.8 us | 0.51 | 0.03 | - | - | - | 47.29 KB | 1.13 | -| | | | | | | | | | | | | | | -| Without | String | 128 | 7,665.5 us | 28.53 us | 38.09 us | 7,662.0 us | 1.00 | 0.00 | - | - | - | 103.65 KB | 1.00 | -| WithXml | String | 128 | 2,392.2 us | 35.64 us | 47.57 us | 2,379.7 us | 0.31 | 0.01 | - | - | - | 74.85 KB | 0.72 | -| WithJson | String | 128 | 2,063.6 us | 26.61 us | 35.53 us | 2,063.5 us | 0.27 | 0.01 | - | - | - | 61.2 KB | 0.59 | -| | | | | | | | | | | | | | | -| Without | String | 512 | 26,444.7 us | 102.44 us | 136.75 us | 26,421.0 us | 1.00 | 0.00 | - | - | - | 343.51 KB | 1.00 | -| WithXml | String | 512 | 8,134.2 us | 32.51 us | 43.41 us | 8,125.8 us | 0.31 | 0.00 | - | - | - | 132.34 KB | 0.39 | -| WithJson | String | 512 | 7,210.9 us | 33.10 us | 44.18 us | 7,199.6 us | 0.27 | 0.00 | - | - | - | 116.42 KB | 0.34 | -| | | | | | | | | | | | | | | -| Without | String | 2048 | 112,512.8 us | 443.78 us | 592.43 us | 112,461.1 us | 1.00 | 0.00 | 5.0000 | - | - | 1310.32 KB | 1.00 | -| WithXml | String | 2048 | 32,080.3 us | 138.18 us | 184.47 us | 32,075.1 us | 0.29 | 0.00 | - | - | - | 361.05 KB | 0.28 | -| WithJson | String | 2048 | 28,929.1 us | 84.67 us | 113.03 us | 28,917.8 us | 0.26 | 0.00 | - | - | - | 336.47 KB | 0.26 | +| Method | Type | NumberOfValues | Mean | Error | StdDev | Median | Ratio | RatioSD | Gen0 | Gen1 | Gen2 | Allocated | Alloc Ratio | +|--------- |------- |--------------- |---------------:|------------:|------------:|---------------:|------:|--------:|-------:|-------:|-------:|----------:|------------:| +| Without | Int32 | 2 | 1,167.3 us | 43.27 us | 57.77 us | 1,143.9 us | 1.00 | 0.00 | - | - | - | 8.7 KB | 1.00 | +| WithXml | Int32 | 2 | 526.3 us | 14.62 us | 19.51 us | 520.8 us | 0.45 | 0.03 | - | - | - | 44.86 KB | 5.16 | +| WithJson | Int32 | 2 | 432.1 us | 16.57 us | 22.12 us | 427.6 us | 0.37 | 0.02 | - | - | - | 31.3 KB | 3.60 | +| | | | | | | | | | | | | | | +| Without | Int32 | 8 | 1,953.4 us | 54.65 us | 72.95 us | 1,959.4 us | 1.00 | 0.00 | - | - | - | 8.77 KB | 1.00 | +| WithXml | Int32 | 8 | 591.3 us | 29.30 us | 39.11 us | 595.6 us | 0.30 | 0.02 | - | - | - | 45.42 KB | 5.18 | +| WithJson | Int32 | 8 | 440.7 us | 11.51 us | 15.37 us | 439.7 us | 0.23 | 0.01 | - | - | - | 31.77 KB | 3.62 | +| | | | | | | | | | | | | | | +| Without | Int32 | 32 | 2,662.0 us | 103.32 us | 137.93 us | 2,688.7 us | 1.00 | 0.00 | - | - | - | 9.12 KB | 1.00 | +| WithXml | Int32 | 32 | 822.3 us | 70.84 us | 94.57 us | 876.3 us | 0.31 | 0.04 | - | - | - | 48.2 KB | 5.29 | +| WithJson | Int32 | 32 | 481.1 us | 21.07 us | 28.13 us | 475.6 us | 0.18 | 0.01 | - | - | - | 33.88 KB | 3.72 | +| | | | | | | | | | | | | | | +| Without | Int32 | 128 | 2,490.2 us | 103.31 us | 137.91 us | 2,490.8 us | 1.00 | 0.00 | - | - | - | 15.37 KB | 1.00 | +| WithXml | Int32 | 128 | 1,941.4 us | 96.33 us | 128.59 us | 1,877.3 us | 0.78 | 0.05 | - | - | - | 59.58 KB | 3.88 | +| WithJson | Int32 | 128 | 604.4 us | 47.16 us | 62.96 us | 624.6 us | 0.24 | 0.03 | - | - | - | 41.5 KB | 2.70 | +| | | | | | | | | | | | | | | +| Without | Int32 | 512 | 2,546.6 us | 129.47 us | 172.84 us | 2,567.5 us | 1.00 | 0.00 | - | - | - | 22.7 KB | 1.00 | +| WithXml | Int32 | 512 | 6,416.5 us | 59.68 us | 79.67 us | 6,403.5 us | 2.53 | 0.17 | - | - | - | 112.25 KB | 4.95 | +| WithJson | Int32 | 512 | 989.7 us | 138.60 us | 185.03 us | 900.3 us | 0.39 | 0.07 | - | - | - | 73.62 KB | 3.24 | +| | | | | | | | | | | | | | | +| Without | Int32 | 2048 | 2,632.8 us | 130.88 us | 174.72 us | 2,636.6 us | 1.00 | 0.00 | - | - | - | 65.01 KB | 1.00 | +| WithXml | Int32 | 2048 | 24,377.3 us | 236.77 us | 316.09 us | 24,251.8 us | 9.30 | 0.64 | - | - | - | 346.68 KB | 5.33 | +| WithJson | Int32 | 2048 | 2,601.5 us | 225.17 us | 300.60 us | 2,479.2 us | 0.99 | 0.13 | - | - | - | 204.41 KB | 3.14 | +| | | | | | | | | | | | | | | +| Without | Guid | 2 | 2,058.0 us | 32.38 us | 43.22 us | 2,047.2 us | 1.00 | 0.00 | - | - | - | 8.92 KB | 1.00 | +| WithXml | Guid | 2 | 517.1 us | 18.83 us | 25.14 us | 515.7 us | 0.25 | 0.01 | - | - | - | 45.23 KB | 5.07 | +| WithJson | Guid | 2 | 440.0 us | 16.36 us | 21.84 us | 438.1 us | 0.21 | 0.01 | - | - | - | 31.56 KB | 3.54 | +| | | | | | | | | | | | | | | +| Without | Guid | 8 | 5,811.5 us | 30.72 us | 41.01 us | 5,806.7 us | 1.00 | 0.00 | - | - | - | 14.17 KB | 1.00 | +| WithXml | Guid | 8 | 573.1 us | 32.34 us | 43.17 us | 580.0 us | 0.10 | 0.01 | - | - | - | 46.64 KB | 3.29 | +| WithJson | Guid | 8 | 461.8 us | 17.77 us | 23.72 us | 460.0 us | 0.08 | 0.00 | - | - | - | 32.66 KB | 2.30 | +| | | | | | | | | | | | | | | +| Without | Guid | 32 | 20,328.2 us | 63.94 us | 85.36 us | 20,340.1 us | 1.00 | 0.00 | - | - | - | 17.83 KB | 1.00 | +| WithXml | Guid | 32 | 771.5 us | 77.67 us | 103.68 us | 838.1 us | 0.04 | 0.01 | - | - | - | 52.9 KB | 2.97 | +| WithJson | Guid | 32 | 525.1 us | 12.43 us | 16.60 us | 521.5 us | 0.03 | 0.00 | - | - | - | 36.57 KB | 2.05 | +| | | | | | | | | | | | | | | +| Without | Guid | 128 | 80,563.7 us | 695.46 us | 928.42 us | 80,338.0 us | 1.000 | 0.00 | - | - | - | 45.43 KB | 1.00 | +| WithXml | Guid | 128 | 1,631.3 us | 103.83 us | 138.60 us | 1,556.0 us | 0.020 | 0.00 | - | - | - | 77.96 KB | 1.72 | +| WithJson | Guid | 128 | 740.5 us | 71.79 us | 95.83 us | 786.8 us | 0.009 | 0.00 | - | - | - | 52.08 KB | 1.15 | +| | | | | | | | | | | | | | | +| Without | Guid | 512 | 330,720.6 us | 646.57 us | 863.15 us | 330,831.7 us | 1.000 | 0.00 | - | - | - | 133.83 KB | 1.00 | +| WithXml | Guid | 512 | 5,109.5 us | 146.38 us | 195.41 us | 5,056.7 us | 0.015 | 0.00 | - | - | - | 184.93 KB | 1.38 | +| WithJson | Guid | 512 | 1,547.3 us | 145.16 us | 193.78 us | 1,425.7 us | 0.005 | 0.00 | - | - | - | 115.97 KB | 0.87 | +| | | | | | | | | | | | | | | +| Without | Guid | 2048 | 1,434,232.2 us | 4,863.00 us | 6,491.96 us | 1,431,593.8 us | 1.000 | 0.00 | 5.0000 | 5.0000 | 5.0000 | 562.98 KB | 1.00 | +| WithXml | Guid | 2048 | 19,451.1 us | 75.68 us | 101.03 us | 19,443.0 us | 0.014 | 0.00 | - | - | - | 637.14 KB | 1.13 | +| WithJson | Guid | 2048 | 5,226.9 us | 214.80 us | 286.75 us | 5,140.3 us | 0.004 | 0.00 | - | - | - | 372.87 KB | 0.66 | +| | | | | | | | | | | | | | | +| Without | String | 2 | 976.7 us | 40.55 us | 54.14 us | 971.1 us | 1.00 | 0.00 | - | - | - | 9.65 KB | 1.00 | +| WithXml | String | 2 | 540.1 us | 13.88 us | 18.53 us | 538.6 us | 0.55 | 0.03 | - | - | - | 45.82 KB | 4.75 | +| WithJson | String | 2 | 516.0 us | 21.13 us | 28.21 us | 514.0 us | 0.53 | 0.04 | - | - | - | 32.14 KB | 3.33 | +| | | | | | | | | | | | | | | +| Without | String | 8 | 2,481.9 us | 43.38 us | 57.91 us | 2,479.8 us | 1.00 | 0.00 | - | - | - | 14.96 KB | 1.00 | +| WithXml | String | 8 | 608.7 us | 30.48 us | 40.69 us | 614.0 us | 0.25 | 0.02 | - | - | - | 47.42 KB | 3.17 | +| WithJson | String | 8 | 617.3 us | 18.08 us | 24.14 us | 613.0 us | 0.25 | 0.01 | - | - | - | 33.66 KB | 2.25 | +| | | | | | | | | | | | | | | +| Without | String | 32 | 8,006.9 us | 44.74 us | 59.73 us | 8,010.0 us | 1.00 | 0.00 | - | - | - | 20.39 KB | 1.00 | +| WithXml | String | 32 | 838.6 us | 83.21 us | 111.08 us | 906.2 us | 0.10 | 0.01 | - | - | - | 53.9 KB | 2.64 | +| WithJson | String | 32 | 849.1 us | 64.67 us | 86.33 us | 892.0 us | 0.11 | 0.01 | - | - | - | 37.95 KB | 1.86 | +| | | | | | | | | | | | | | | +| Without | String | 128 | 31,372.5 us | 58.88 us | 78.60 us | 31,382.7 us | 1.00 | 0.00 | - | - | - | 52.91 KB | 1.00 | +| WithXml | String | 128 | 1,802.2 us | 146.18 us | 195.14 us | 1,690.7 us | 0.06 | 0.01 | - | - | - | 79.74 KB | 1.51 | +| WithJson | String | 128 | 1,863.0 us | 130.62 us | 174.38 us | 1,758.8 us | 0.06 | 0.01 | - | - | - | 56.59 KB | 1.07 | +| | | | | | | | | | | | | | | +| Without | String | 512 | 133,130.3 us | 634.15 us | 846.57 us | 133,481.7 us | 1.00 | 0.00 | - | - | - | 165.83 KB | 1.00 | +| WithXml | String | 512 | 5,911.6 us | 134.15 us | 179.08 us | 5,872.8 us | 0.04 | 0.00 | - | - | - | 190.35 KB | 1.15 | +| WithJson | String | 512 | 6,672.9 us | 165.38 us | 220.78 us | 6,638.3 us | 0.05 | 0.00 | - | - | - | 131.24 KB | 0.79 | +| | | | | | | | | | | | | | | +| Without | String | 2048 | 535,679.0 us | 977.69 us | 1,305.19 us | 535,368.9 us | 1.00 | 0.00 | 5.0000 | 5.0000 | 5.0000 | 687.4 KB | 1.00 | +| WithXml | String | 2048 | 22,191.9 us | 65.79 us | 87.83 us | 22,189.3 us | 0.04 | 0.00 | - | - | - | 655.65 KB | 0.95 | +| WithJson | String | 2048 | 27,953.3 us | 133.58 us | 178.32 us | 27,962.5 us | 0.05 | 0.00 | - | - | - | 432.27 KB | 0.63 |
+### Version Archive + +- [`7.2.0`](/docs/benchmarks/v7.2.0.md) + --- ## Background πŸ“š @@ -362,6 +363,8 @@ WHERE [m].[MyEntityID] IN (1, 2, 3, 4) OR ([m].[PropB] = @__p_1)',N'@__p_1 bigin ``` As we can see, a new SQL statement was generated just because we modified the list that's being used in our `Where` predicate. This has the detrimental effect that a previously cached execution plan cannot be reused, forcing SQL Server's query engine to compute a new [execution plan] *every time* it is provided with a SQL statement that it hasn't seen before and increasing the likelihood of flushing other plans in the process. +> πŸ’‘ To address this issue, EF8 now incorporates the use of the [`OPENJSON`] function when possible. The change was tracked by this [EF Core issue](https://github.com/dotnet/efcore/issues/13617). As of EF version `8.0.0`, QueryableValues remains superior in terms of compatibility and performance. + ## Enter AsQueryableValues πŸ™Œ ![Parameterize All the Things](/docs/images/parameterize-all-the-things.jpg) @@ -426,24 +429,6 @@ QueryableValues makes use of the XML parsing capabilities in SQL Server, which a This is a technique that I have not seen being used by other popular libraries that aim to solve this problem. It is superior from a latency standpoint because it resolves the query with a single round trip to the database and most importantly, it preserves the query's [execution plan] even when the content of the XML is changed. -## One More Thing πŸ‘€ -The `AsQueryableValues` extension method allows you to treat a sequence of values as you normally would if they were another entity in your [DbContext]. The type returned by the extension is an [IQueryable<T>] that can be composed with other entities in your query. - -For example, you can perform one or more joins like this and it is completely fine: -```c# -var myQuery = - from i in dbContext.MyEntities - join v in dbContext.AsQueryableValues(values) on i.MyEntityID equals v - join v2 in dbContext.AsQueryableValues(values2) on i.PropB equals v2 - select new - { - i.MyEntityID, - i.PropA - }; -``` - -Isn't that great? πŸ₯° - ## Did You Find a πŸ› or Have an πŸ’‘? PRs are welcome! πŸ™‚ @@ -471,6 +456,8 @@ PRs are welcome! πŸ™‚ [Double]: https://docs.microsoft.com/en-us/dotnet/api/system.double [DateTime]: https://docs.microsoft.com/en-us/dotnet/api/system.datetime [DateTimeOffset]: https://docs.microsoft.com/en-us/dotnet/api/system.datetimeoffset +[DateOnly]: https://docs.microsoft.com/en-us/dotnet/api/system.dateonly +[TimeOnly]: https://docs.microsoft.com/en-us/dotnet/api/system.timeonly [Guid]: https://docs.microsoft.com/en-us/dotnet/api/system.guid [Char]: https://docs.microsoft.com/en-us/dotnet/api/system.char [String]: https://docs.microsoft.com/en-us/dotnet/api/system.string @@ -480,5 +467,6 @@ PRs are welcome! πŸ™‚ [Repository]: https://github.com/yv989c/BlazarTech.QueryableValues [benchmarks]: /benchmarks/QueryableValues.SqlServer.Benchmarks -[BenchmarksChart]: /docs/images/benchmarks/v7.2.0.png -[BenchmarksChartInteractive]: https://chartbenchmark.net/?src=repo#shared=%7B%22results%22%3A%22BenchmarkDotNet%3Dv0.13.5%2C%20OS%3DWindows%2011%20(10.0.22621.1413%2F22H2%2F2022Update%2FSunValley2)%5CnAMD%20Ryzen%209%206900HS%20Creator%20Edition%2C%201%20CPU%2C%2016%20logical%20and%208%20physical%20cores%5Cn.NET%20SDK%3D7.0.202%5Cn%20%20%5BHost%5D%20%20%20%20%20%3A%20.NET%206.0.15%20(6.0.1523.11507)%2C%20X64%20RyuJIT%20AVX2%5Cn%20%20Job-OFVMJD%20%3A%20.NET%206.0.15%20(6.0.1523.11507)%2C%20X64%20RyuJIT%20AVX2%5Cn%5CnServer%3DTrue%20%20InvocationCount%3D200%20%20IterationCount%3D25%5CnRunStrategy%3DMonitoring%20%20UnrollFactor%3D1%20%20WarmupCount%3D1%5Cn%5Cn%7C%20%20%20Method%20%7C%20%20%20Type%20%7C%20NumberOfValues%20%7C%20%20%20%20%20%20%20%20%20Mean%20%7C%20%20%20%20%20Error%20%7C%20%20%20%20StdDev%20%7C%20%20%20%20%20%20%20Median%20%7C%20Ratio%20%7C%20RatioSD%20%7C%20%20%20Gen0%20%7C%20%20%20Gen1%20%7C%20%20%20Gen2%20%7C%20%20Allocated%20%7C%20Alloc%20Ratio%20%7C%5Cn%7C---------%20%7C-------%20%7C---------------%20%7C-------------%3A%7C----------%3A%7C----------%3A%7C-------------%3A%7C------%3A%7C--------%3A%7C-------%3A%7C-------%3A%7C-------%3A%7C-----------%3A%7C------------%3A%7C%5Cn%7C%20%20Without%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%202%20%7C%20%20%20%20%20824.3%20us%20%7C%20%2026.03%20us%20%7C%20%2034.75%20us%20%7C%20%20%20%20%20808.9%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2020.26%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%202%20%7C%20%20%20%20%20508.7%20us%20%7C%20%2032.46%20us%20%7C%20%2043.34%20us%20%7C%20%20%20%20%20504.3%20us%20%7C%20%200.62%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2041.37%20KB%20%7C%20%20%20%20%20%20%20%202.04%20%7C%5Cn%7C%20WithJson%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%202%20%7C%20%20%20%20%20431.7%20us%20%7C%20%2035.52%20us%20%7C%20%2047.41%20us%20%7C%20%20%20%20%20446.8%20us%20%7C%20%200.52%20%7C%20%20%20%200.05%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%2041.5%20KB%20%7C%20%20%20%20%20%20%20%202.05%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%208%20%7C%20%20%20%20%20964.8%20us%20%7C%20%2025.05%20us%20%7C%20%2033.44%20us%20%7C%20%20%20%20%20954.6%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2021.17%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%208%20%7C%20%20%20%20%20548.2%20us%20%7C%20%2034.29%20us%20%7C%20%2045.78%20us%20%7C%20%20%20%20%20537.0%20us%20%7C%20%200.57%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2041.33%20KB%20%7C%20%20%20%20%20%20%20%201.95%20%7C%5Cn%7C%20WithJson%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%208%20%7C%20%20%20%20%20445.1%20us%20%7C%20%2034.28%20us%20%7C%20%2045.76%20us%20%7C%20%20%20%20%20453.6%20us%20%7C%20%200.46%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2041.56%20KB%20%7C%20%20%20%20%20%20%20%201.96%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%2032%20%7C%20%20%201%2C519.3%20us%20%7C%20%2034.23%20us%20%7C%20%2045.69%20us%20%7C%20%20%201%2C494.4%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2025.45%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%2032%20%7C%20%20%20%20%20687.5%20us%20%7C%20%2032.29%20us%20%7C%20%2043.10%20us%20%7C%20%20%20%20%20664.9%20us%20%7C%20%200.45%20%7C%20%20%20%200.03%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2041.52%20KB%20%7C%20%20%20%20%20%20%20%201.63%20%7C%5Cn%7C%20WithJson%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%2032%20%7C%20%20%20%20%20448.1%20us%20%7C%20%2038.22%20us%20%7C%20%2051.03%20us%20%7C%20%20%20%20%20425.9%20us%20%7C%20%200.30%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2041.61%20KB%20%7C%20%20%20%20%20%20%20%201.63%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20128%20%7C%20%20%205%2C470.2%20us%20%7C%20%2025.34%20us%20%7C%20%2033.83%20us%20%7C%20%20%205%2C473.2%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2041.18%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20128%20%7C%20%20%201%2C334.4%20us%20%7C%20%2037.80%20us%20%7C%20%2050.47%20us%20%7C%20%20%201%2C316.5%20us%20%7C%20%200.24%20%7C%20%20%20%200.01%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2044.02%20KB%20%7C%20%20%20%20%20%20%20%201.07%20%7C%5Cn%7C%20WithJson%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20128%20%7C%20%20%20%20%20498.9%20us%20%7C%20%2033.69%20us%20%7C%20%2044.97%20us%20%7C%20%20%20%20%20498.1%20us%20%7C%20%200.09%20%7C%20%20%20%200.01%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2042.53%20KB%20%7C%20%20%20%20%20%20%20%201.03%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20512%20%7C%20%2017%2C572.2%20us%20%7C%20%2068.50%20us%20%7C%20%2091.45%20us%20%7C%20%2017%2C566.4%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20105.67%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20512%20%7C%20%20%204%2C016.2%20us%20%7C%20%2030.74%20us%20%7C%20%2041.04%20us%20%7C%20%20%204%2C014.4%20us%20%7C%20%200.23%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2052.18%20KB%20%7C%20%20%20%20%20%20%20%200.49%20%7C%5Cn%7C%20WithJson%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20512%20%7C%20%20%20%20%20685.0%20us%20%7C%20%2030.40%20us%20%7C%20%2040.59%20us%20%7C%20%20%20%20%20661.9%20us%20%7C%20%200.04%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2046.37%20KB%20%7C%20%20%20%20%20%20%20%200.44%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%202048%20%7C%20%2071%2C616.8%20us%20%7C%20677.00%20us%20%7C%20903.77%20us%20%7C%20%2071%2C227.6%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20363.17%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%202048%20%7C%20%2014%2C045.8%20us%20%7C%20%2050.55%20us%20%7C%20%2067.48%20us%20%7C%20%2014%2C029.9%20us%20%7C%20%200.20%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2084.85%20KB%20%7C%20%20%20%20%20%20%20%200.23%20%7C%5Cn%7C%20WithJson%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%202048%20%7C%20%20%201%2C577.1%20us%20%7C%20%2032.17%20us%20%7C%20%2042.95%20us%20%7C%20%20%201%2C564.8%20us%20%7C%20%200.02%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2061.07%20KB%20%7C%20%20%20%20%20%20%20%200.17%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%202%20%7C%20%20%20%20%20788.9%20us%20%7C%20%2020.31%20us%20%7C%20%2027.11%20us%20%7C%20%20%20%20%20778.1%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2020.74%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%202%20%7C%20%20%20%20%20487.6%20us%20%7C%20%2030.51%20us%20%7C%20%2040.74%20us%20%7C%20%20%20%20%20487.7%20us%20%7C%20%200.62%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2041.23%20KB%20%7C%20%20%20%20%20%20%20%201.99%20%7C%5Cn%7C%20WithJson%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%202%20%7C%20%20%20%20%20434.7%20us%20%7C%20%2033.42%20us%20%7C%20%2044.61%20us%20%7C%20%20%20%20%20443.3%20us%20%7C%20%200.55%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2041.19%20KB%20%7C%20%20%20%20%20%20%20%201.99%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%208%20%7C%20%20%20%20%20939.1%20us%20%7C%20%2029.24%20us%20%7C%20%2039.04%20us%20%7C%20%20%20%20%20921.1%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2023.49%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%208%20%7C%20%20%20%20%20515.1%20us%20%7C%20%2032.95%20us%20%7C%20%2043.99%20us%20%7C%20%20%20%20%20509.2%20us%20%7C%20%200.55%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2042.23%20KB%20%7C%20%20%20%20%20%20%20%201.80%20%7C%5Cn%7C%20WithJson%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%208%20%7C%20%20%20%20%20450.0%20us%20%7C%20%2033.55%20us%20%7C%20%2044.79%20us%20%7C%20%20%20%20%20461.4%20us%20%7C%20%200.48%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2041.98%20KB%20%7C%20%20%20%20%20%20%20%201.79%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%2032%20%7C%20%20%201%2C566.2%20us%20%7C%20%2043.12%20us%20%7C%20%2057.56%20us%20%7C%20%20%201%2C551.3%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2033.24%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%2032%20%7C%20%20%20%20%20607.3%20us%20%7C%20%2033.01%20us%20%7C%20%2044.07%20us%20%7C%20%20%20%20%20587.0%20us%20%7C%20%200.39%20%7C%20%20%20%200.03%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2043.58%20KB%20%7C%20%20%20%20%20%20%20%201.31%20%7C%5Cn%7C%20WithJson%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%2032%20%7C%20%20%20%20%20488.4%20us%20%7C%20%2032.86%20us%20%7C%20%2043.87%20us%20%7C%20%20%20%20%20487.3%20us%20%7C%20%200.31%20%7C%20%20%20%200.03%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2043.48%20KB%20%7C%20%20%20%20%20%20%20%201.31%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20128%20%7C%20%20%205%2C140.0%20us%20%7C%20%2052.22%20us%20%7C%20%2069.71%20us%20%7C%20%20%205%2C138.2%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2074.11%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20128%20%7C%20%20%20%20%20987.8%20us%20%7C%20%2037.30%20us%20%7C%20%2049.79%20us%20%7C%20%20%20%20%20965.0%20us%20%7C%20%200.19%20%7C%20%20%20%200.01%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2051.97%20KB%20%7C%20%20%20%20%20%20%20%200.70%20%7C%5Cn%7C%20WithJson%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20128%20%7C%20%20%20%20%20665.9%20us%20%7C%20%2038.37%20us%20%7C%20%2051.23%20us%20%7C%20%20%20%20%20636.8%20us%20%7C%20%200.13%20%7C%20%20%20%200.01%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2051.12%20KB%20%7C%20%20%20%20%20%20%20%200.69%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20512%20%7C%20%2016%2C031.0%20us%20%7C%20%2074.08%20us%20%7C%20%2098.89%20us%20%7C%20%2016%2C023.7%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20219.5%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20512%20%7C%20%20%202%2C528.8%20us%20%7C%20%2038.80%20us%20%7C%20%2051.79%20us%20%7C%20%20%202%2C517.7%20us%20%7C%20%200.16%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2084.36%20KB%20%7C%20%20%20%20%20%20%20%200.38%20%7C%5Cn%7C%20WithJson%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20512%20%7C%20%20%201%2C368.8%20us%20%7C%20%2022.42%20us%20%7C%20%2029.93%20us%20%7C%20%20%201%2C355.1%20us%20%7C%20%200.09%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2080.08%20KB%20%7C%20%20%20%20%20%20%20%200.36%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%202048%20%7C%20%2071%2C956.6%20us%20%7C%20688.35%20us%20%7C%20918.93%20us%20%7C%20%2072%2C148.6%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20801.13%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%202048%20%7C%20%20%209%2C399.9%20us%20%7C%20%2076.33%20us%20%7C%20101.90%20us%20%7C%20%20%209%2C359.8%20us%20%7C%20%200.13%20%7C%20%20%20%200.00%20%7C%205.0000%20%7C%205.0000%20%7C%205.0000%20%7C%20%20213.42%20KB%20%7C%20%20%20%20%20%20%20%200.27%20%7C%5Cn%7C%20WithJson%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%202048%20%7C%20%20%204%2C463.6%20us%20%7C%20%2036.90%20us%20%7C%20%2049.26%20us%20%7C%20%20%204%2C442.6%20us%20%7C%20%200.06%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20197.4%20KB%20%7C%20%20%20%20%20%20%20%200.25%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%202%20%7C%20%20%20%20%20858.7%20us%20%7C%20%2023.34%20us%20%7C%20%2031.16%20us%20%7C%20%20%20%20%20846.2%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2021.44%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%202%20%7C%20%20%20%20%20637.4%20us%20%7C%20%2035.57%20us%20%7C%20%2047.48%20us%20%7C%20%20%20%20%20626.0%20us%20%7C%20%200.74%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2055.52%20KB%20%7C%20%20%20%20%20%20%20%202.59%20%7C%5Cn%7C%20WithJson%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%202%20%7C%20%20%20%20%20534.5%20us%20%7C%20%2030.81%20us%20%7C%20%2041.13%20us%20%7C%20%20%20%20%20528.7%20us%20%7C%20%200.62%20%7C%20%20%20%200.03%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2042.83%20KB%20%7C%20%20%20%20%20%20%20%202.00%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%208%20%7C%20%20%201%2C028.9%20us%20%7C%20%2024.07%20us%20%7C%20%2032.13%20us%20%7C%20%20%201%2C015.2%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2025.55%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%208%20%7C%20%20%20%20%20737.8%20us%20%7C%20%2044.23%20us%20%7C%20%2059.05%20us%20%7C%20%20%20%20%20727.5%20us%20%7C%20%200.72%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2056.98%20KB%20%7C%20%20%20%20%20%20%20%202.23%20%7C%5Cn%7C%20WithJson%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%208%20%7C%20%20%20%20%20641.8%20us%20%7C%20%2034.63%20us%20%7C%20%2046.23%20us%20%7C%20%20%20%20%20640.1%20us%20%7C%20%200.62%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2043.64%20KB%20%7C%20%20%20%20%20%20%20%201.71%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%2032%20%7C%20%20%201%2C692.5%20us%20%7C%20%2023.43%20us%20%7C%20%2031.27%20us%20%7C%20%20%201%2C684.7%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2041.84%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%2032%20%7C%20%20%201%2C016.7%20us%20%7C%20%2056.75%20us%20%7C%20%2075.76%20us%20%7C%20%20%20%20%20976.6%20us%20%7C%20%200.60%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2060.35%20KB%20%7C%20%20%20%20%20%20%20%201.44%20%7C%5Cn%7C%20WithJson%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%2032%20%7C%20%20%20%20%20871.5%20us%20%7C%20%2039.02%20us%20%7C%20%2052.10%20us%20%7C%20%20%20%20%20843.8%20us%20%7C%20%200.51%20%7C%20%20%20%200.03%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2047.29%20KB%20%7C%20%20%20%20%20%20%20%201.13%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20128%20%7C%20%20%207%2C665.5%20us%20%7C%20%2028.53%20us%20%7C%20%2038.09%20us%20%7C%20%20%207%2C662.0%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20103.65%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20128%20%7C%20%20%202%2C392.2%20us%20%7C%20%2035.64%20us%20%7C%20%2047.57%20us%20%7C%20%20%202%2C379.7%20us%20%7C%20%200.31%20%7C%20%20%20%200.01%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2074.85%20KB%20%7C%20%20%20%20%20%20%20%200.72%20%7C%5Cn%7C%20WithJson%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20128%20%7C%20%20%202%2C063.6%20us%20%7C%20%2026.61%20us%20%7C%20%2035.53%20us%20%7C%20%20%202%2C063.5%20us%20%7C%20%200.27%20%7C%20%20%20%200.01%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%2061.2%20KB%20%7C%20%20%20%20%20%20%20%200.59%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20512%20%7C%20%2026%2C444.7%20us%20%7C%20102.44%20us%20%7C%20136.75%20us%20%7C%20%2026%2C421.0%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20343.51%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20512%20%7C%20%20%208%2C134.2%20us%20%7C%20%2032.51%20us%20%7C%20%2043.41%20us%20%7C%20%20%208%2C125.8%20us%20%7C%20%200.31%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20132.34%20KB%20%7C%20%20%20%20%20%20%20%200.39%20%7C%5Cn%7C%20WithJson%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20512%20%7C%20%20%207%2C210.9%20us%20%7C%20%2033.10%20us%20%7C%20%2044.18%20us%20%7C%20%20%207%2C199.6%20us%20%7C%20%200.27%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20116.42%20KB%20%7C%20%20%20%20%20%20%20%200.34%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%202048%20%7C%20112%2C512.8%20us%20%7C%20443.78%20us%20%7C%20592.43%20us%20%7C%20112%2C461.1%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%205.0000%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%201310.32%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%202048%20%7C%20%2032%2C080.3%20us%20%7C%20138.18%20us%20%7C%20184.47%20us%20%7C%20%2032%2C075.1%20us%20%7C%20%200.29%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20361.05%20KB%20%7C%20%20%20%20%20%20%20%200.28%20%7C%5Cn%7C%20WithJson%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%202048%20%7C%20%2028%2C929.1%20us%20%7C%20%2084.67%20us%20%7C%20113.03%20us%20%7C%20%2028%2C917.8%20us%20%7C%20%200.26%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20336.47%20KB%20%7C%20%20%20%20%20%20%20%200.26%20%7C%5Cn%22%2C%22settings%22%3A%7B%22display%22%3A%22Duration%22%2C%22scale%22%3A%22Log2%22%2C%22theme%22%3A%22Dark%22%7D%7D "Click for interactive chart" \ No newline at end of file +[BenchmarksChart]: /docs/benchmarks/images/v8.1.0.png +[BenchmarksChartInteractive]: https://chartbenchmark.net/#shared=%7B%22v%22%3A1%2C%22settings%22%3A%7B%22display%22%3A%22Duration%22%2C%22scale%22%3A%22Log2%22%2C%22theme%22%3A%22Dark%22%7D%2C%22results%22%3A%22EIUwdgxgFgtghgJwNYBED2AXAciDACANwAYA6ARgGZyiAaPAdQEswATNAdwGc8yy8AKMqVIAmEQDYRZEiIDsZAKwB6MQAkRKomICqABxZwMIJQGUArmABqcADY2QATxEBKAFABBALIo8AJQcAXuB4AJx44iFERKomeADCCCCGaAh4AKIsjBiMaGB0fHEACtr54ng2aADmjBC2eHCseAAceLpQDpw1dRApIJyuJFhpACp4JigA0s0kpEJErnh4ANqqaJwYALqL2wBceIMj08ICTTMyVAoUQhTOdAAa4gAsfg5mAFIAkqPulnciC3g3mgAEYAWjSwHc7jeADE8HsDqNTsd%2BMjziRLtdbngHs9%2FO8vngfn9XK4TCAEAQKQBeYYIMwgRYfMAENC1bK5OJoCwYakiKJMowIQw5MBcnl8hSuXwWEwYYVGSoOameXJZFLMSqLbRgBBoOwwuAQDApal8BiIGBmXTisC8sikgA%2BeE8uCgaBY22dwwcukZi2dWDMMGBFIA8gAzaw2BncZ2uhrbJNJ51pBB61LJvDOuUsFAgAhZ%2BMgTKJrMBvwitDZysc8Y1gDi4CIXrwTbA5sb4BErfcdjZhhLNb7FQgtZy2dcjtBM9ns%2Bzc%2Fn08XK6Xq%2FXO2X65nm%2B3s93e7nB6PW8Xx5Pq%2FP%2B9PK6vl8dU4YWXdZnwNeZGAoPZr3%2FLyedSZkDQZDiLIJAUHgZhxkmjxUHIkHQdsChgbIsgITWgHAbBJBhFBGHSAKAGLMILZEdsoIYUmFFkYs1FJqcaETMAlHJgRpGPkwGBQHcMA2BWH5fhWv5%2Fq2WYKBI4HoWRZCPCQkhSYBIQYnweE0Ys4mkC0qnESQjwKCxwgQWpdHJiZVEYY8slNGUTEsUmCjkGUD7OpxUBvJwuTvnagk%2FiJ%2F7lrBIjkAp2wgRiaHadsYjkD2kXJo8chySFpAUGhZHCD2xl2XgZnkZRVySbZamLFQ4jscVolFn5VXVSmtXZeWFV%2FsVTUVW1zXVU1KYcc%2B3Jvs6Anfs6LT1TRQEhJcukhepsniPpcV4LIQUTdNizjQoSnPJFbEGTMpFZrltHZWZDGMcxFU7c5T5cTxfFeZ%2BQ3NPVDUbdIEELSISkUC2C0UEpvCrUhE1JZFKX7dsGXHVDWUAXpuk9kVf4OWQLRXa57meQN3mPSNtXFZZpARYha3SAoKnEzwDmpYDiywUpRMYaIRlJsIfAwwd0MldIqF4Ij5alZlj4ie1z0NcLo0S6LLXi41HWy35XVej1XF9fx2MVj5nXJiINDiJIMzTdc4GxcTlBgSE70U3gOviE0DEhZdLN7Zzpku6EMW8%2Bdf6Xcr3G8WrD0a8JMvJk00WWyxsiaVtFMhLJyE080sjiJJoPgWzTtEM87OuzneCPKcCNe%2BWDmfZOLnPhjYD3T5zqawrAVNNI5MsVIMwM2RIinJQiePLIDllGnKO7UQGe5xzOcUFQdue2LVBLeXDfy89iv%2BXjksr8vNXb2vO9b8LvuqzXj1kF369JjrjyRDIhtEFQVyG6lOEtzRl%2FX1piGOxDzt53lOeKOBM6YsfYVxuv7Y%2BFZT64xDmtGgcdpAxxYiEFOU9DZdwxLhK2QEmioVTohQmqNM76V%2FkdHOG0MQtD5lmaeqNfZVwgTWKB59kxlVkogsifdHKrX1sgxOkhZrJRkNnTOzNx5iPMkRR4pNZ4VSClHReMC6pS1FmLXeS9N57yUZois%2B9tFFkPq%2BAOtc8Bk2DvvHWChHgp0HqbT6ukO6hSWiQJo7DtY0AUKBDEDsf6Z3BhIieATFjRSARdH%2BvtbpGMeqY5hixxA0CkSneaFNyG21WrIJSoFAZxMeHfLxkUgqXF2mQNKgT%2FHj14EFEQ%2BkqHxRwsQuhHlq5Y0DjWaJWsswhCaPTR%2BpwyqGyaA5O%2BidIgpUEX9EeJTxF%2F0CbIAWMi%2FxwWzkLOWeiVkb3URsmJlU9Ei1WTozqBj%2Bp4EGkJLO0DzG6y%2FM4x%2BmkP6UWKbJBeC1raXOsd4wivi3bTLEXNGYfAamATCaAv2d1mnGP5AXdpQTHg0FSmBCORERAUBTjzOKVwU5EEwa3GFVTpB3IAl9PxeBSBPC%2BaQgJFArFyUocXMS4EjINMxsc9WP4zlQqCbrUeeTiZiGRg4kqUQ5I%2FStpfdJN804hDCOlcgoiylyumRC3S%2FzaXJioDJBRaytHrK2Zq3Vmz9k7L1aog1B9gVH2dA2MwjBPRCQ0VFGgRAFDIlWlcig%2BKYJwRNnZHWWcwJeoAl%2FHSHypnkvEacEIRdgFAuuiCislrrWtjMXqsmYEX6AVOE0BFF9kauLEgA%2FlohiGZzHvK0NZS4ZIvmSXdui90aNMbFam1vltW0xyQbBaYVkWrTbi43ubrgppykCPEt3zS05QwgVDxVbqEYiWV1XZLb9W6OXYok1Wr13bI3Wo01MbzVtkba2c5iiFA0CbtI36hN%2FUwQImm%2Byp6iAoveUSkiZLx3%2F1ksU6drFo2uQiQ2hNFYj3JtmQOimrrc20zVfy5MTrjhD2fX819h03202sc8AF2w4JSsZU0%2FdAGaxAeXVYvFq1ikkFRRTJF5Gr1ZisXB%2FBMxCHf2DWO5DJkrl6y%2FRfcC5Ul3Gr2QJtdK69WtSNQu4T3UzWGP%2FU2uuSad78lhegmjsSqBx1WgM8CNjW60EpbMJ9I8iVltHd8sjmauOhR%2Fc%2BP9FqD1B0Xahc9FNcGZLikbVJzzFiZu7oIrOw6kNu3EjhCzQScJpRwzJ1s9dV0mKqaBlip9dJZtCtY4VL025JMZjMWVxKfEhpQ2I5F4UQvWxmPU%2BdRrKsSc3VV7RomV3icE7W3q0nbP4edEw9lTRaAePntNCIDkrHTQjacBKGndP9rSx1vaCGWMmeM6GuGsESsgJjTZvDsmeBn3ZTwS5b1b7T2SzwftfTnlAQUB49t0EMqzaMwV1jGFcG8Iw2tajzWuL0La5tzrS7ZBtsy2ReQ5GsVkWBuZzzi1rLXO0iRKVnySH3e%2BUFogNKo2KA1Q1lRq8t1NexzV1RjWhP8ex2jFrRz42bbaeoqetAlokv61ShOcVrJqoB5h76p6CoOLYrdgL7NKCHZW1ZsBoKNutip8e4CmLuX3KpW6w2wMpGAxPY6x9MO%2FlFuY3dtjnMUayQtkL%2BXpOPv1q%2B%2BL0%2BWzzucKOzJZG2miJkAtuR91mEEoOQcSRTXQbtd854AAkIIS%2FyaXCxV6r26du1aJyJmLYtCc4%2F%2FIcuNdnWWQobkBWCOKrlXphSz522lskhGkLw7S6erjuKd%2B6nnhnWkzf2oMqIdfa%2BtJ4aj0JhFwngLN6c1PMDHfxLJvFwHA8Xc8C5UMjtIR4nYSm7l0ewite%2B%2FHuIJ%2B6qXs8Ble9typuxfd8I5uk9YgU4g6ijJZxM%2BglQ%2F7srrCoz1dRHn97xf%2FjUpBRwSVklTllmY%2BUT%2FiPYet31aGrVYk6J41hygICajNo6qhDJzkarT%2FZs5IQfoQZJgB7NwGbSpzYLaI5loZLVIqqArt7ArrbgGQHOjybaKWL6Ydo0KkanCFIQ6XC9KCIXYjw5bYE66wwORhwlaPLlYxqfZjDyhkHWx2r2RhTn5BLNxHbWyFy3owan7n6kCFKYEP7zY4EFZXKr4EGYb0oY5AFiHQG45Y7CZx5x7476JSZHKkFgBajDSGGXxNzBYLTYTy4LTITPyAyipKQu6Bqz4%2B4I4mSn7PY6GvZEFrad5CEQG2EEaGGxIo5wEXq6Qj75wkrH5ZjiCKGCJVIjyZSlLqEmScJjZr5Qab6CE2F2FPSLqZHwp0GMbdrIF8KUBXZZY5GYEjocEuxTxyQ2ShGlZtFf4GGLox7h7%2F746AGjGx5%2F6WG7qtZREiHRaapNAOoPrOEUyWTkYoHkKzKAzLGjz0b4R5aP6BEuz8jgRhBr6ra%2FqREVE1iLHLreYgwUyZoyDyG8AEQpHbCRApw0azCzYdEaGcFIRqYlZBSkrG5b5Mq3FyaLouL%2FTcKzTQbNAoIyHbBdJBRKHkAjqsxP7fJPwrSXHOKf6h5NYWGR78ZR7LoTE47mGUlKxWEVjQlbZ77bJl4v4y5kROrOIpGyC9KSF4BslhyJGfxHH%2BG4mhpBaF5C7hHXGi5Mk%2FaKLYJaDiqmxUrDxubAzqpna6zXwFozBOTFrikFZip%2FZC5kxlHb7ynbabLYLL4tEO7fRyQqYPLgSfFAT9wZq%2BYGnMYAlAliKXYbTSkh58Z450mTHhnx5Ukx5mHTEJ4MlgHCExHOgS4rIC7ASOlHbL4fqIHNCM7QZpkFzcwYHw75GdEda%2FLmaEkynWY3GJmVEpn7wnqF7SD26hSUrkA5nFJKQo7X44Kv6%2BZqEvonH87XwUD4Fo78F1pQl1mtIW47ZxKgTLSGy%2FJuE8pnG8lZKXKnDJbCBe5inDkBKUDSAiDoZ9GEzYYkkRmklhkUm3njHRliaxmSazHWEznkFsrqKXAnqgTdnDYubH5ATfTIzpEmJjmwq2xrGHFzZDkmJN7JlwWwUN7gy2xgSnlRrVki6MlvnWwfkwJiDASF6QVkS%2FLpIaZgTg6UY6woxfQDnV4HlL4XZyTjkVSkArQQnlHYUQosmtyyBwKTQ27dFOqGy8nGzdq8XIIFK%2BZ7kwX5ZAmBQyCB7lgkpGRAA%3D%3D%22%7D "Click for interactive chart" +[`OPENJSON`]: https://learn.microsoft.com/en-us/sql/t-sql/functions/openjson-transact-sql \ No newline at end of file diff --git a/Version.xml b/Version.xml index cddd0fa..2bd5371 100644 --- a/Version.xml +++ b/Version.xml @@ -1,9 +1,9 @@ ο»Ώ - 3.9.1 - 5.9.1 - 6.9.1 - 7.4.1 - 8.0.0 + 3.9.2 + 5.9.2 + 6.9.2 + 7.4.2 + 8.1.0 \ No newline at end of file diff --git a/benchmarks/QueryableValues.SqlServer.Benchmarks/ContainsBenchmarks.cs b/benchmarks/QueryableValues.SqlServer.Benchmarks/ContainsBenchmarks.cs index 7296a47..8c33d79 100644 --- a/benchmarks/QueryableValues.SqlServer.Benchmarks/ContainsBenchmarks.cs +++ b/benchmarks/QueryableValues.SqlServer.Benchmarks/ContainsBenchmarks.cs @@ -8,6 +8,7 @@ namespace QueryableValues.SqlServer.Benchmarks; +//[SimpleJob(RunStrategy.Monitoring, warmupCount: 1, iterationCount: 1, invocationCount: 6)] [SimpleJob(RunStrategy.Monitoring, warmupCount: 1, iterationCount: 25, invocationCount: 200)] [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)] [GcServer(true), MemoryDiagnoser] diff --git a/benchmarks/QueryableValues.SqlServer.Benchmarks/QueryableValues.SqlServer.Benchmarks.csproj b/benchmarks/QueryableValues.SqlServer.Benchmarks/QueryableValues.SqlServer.Benchmarks.csproj index 40380b1..5c81346 100644 --- a/benchmarks/QueryableValues.SqlServer.Benchmarks/QueryableValues.SqlServer.Benchmarks.csproj +++ b/benchmarks/QueryableValues.SqlServer.Benchmarks/QueryableValues.SqlServer.Benchmarks.csproj @@ -2,18 +2,18 @@ Exe - net6.0 + net8.0 enable enable - - + + - + diff --git a/docs/README.md b/docs/README.md index 0306576..dd29d08 100644 --- a/docs/README.md +++ b/docs/README.md @@ -18,9 +18,6 @@ For a detailed explanation of the problem solved by QueryableValues, please cont > πŸ’‘ Still on Entity Framework 6 (non-core)? Then [QueryableValues `EF6 Edition`](https://github.com/yv989c/BlazarTech.QueryableValues.EF6) is what you need. -## When Should You Use It? -The `AsQueryableValues` extension method is intended for queries that are dependent upon a *non-constant* sequence of external values. It provides a solution to the following [EF Core issue](https://github.com/dotnet/efcore/issues/13617) and enables other currently unsupported scenarios; like the ability to efficiently create joins with in-memory data. - ## Your Support is Appreciated! If you feel that this solution has provided you some value, please consider [buying me a β˜•][BuyMeACoffee]. @@ -88,7 +85,7 @@ Below are a few examples composing a query using the values provided by an [IEnu ### Simple Type Examples -> πŸ’‘ Supports [Byte], [Int16], [Int32], [Int64], [Decimal], [Single], [Double], [DateTime], [DateTimeOffset], [Guid], [Char], [String], and [Enum]. +> πŸ’‘ Supports [Byte], [Int16], [Int32], [Int64], [Decimal], [Single], [Double], [DateTime], [DateTimeOffset], [DateOnly], [TimeOnly], [Guid], [Char], [String], and [Enum]. Using the [Contains][ContainsQueryable] LINQ method: @@ -215,6 +212,8 @@ Please take a look at the [repository][Repository]. [Double]: https://docs.microsoft.com/en-us/dotnet/api/system.double [DateTime]: https://docs.microsoft.com/en-us/dotnet/api/system.datetime [DateTimeOffset]: https://docs.microsoft.com/en-us/dotnet/api/system.datetimeoffset +[DateOnly]: https://docs.microsoft.com/en-us/dotnet/api/system.dateonly +[TimeOnly]: https://docs.microsoft.com/en-us/dotnet/api/system.timeonly [Guid]: https://docs.microsoft.com/en-us/dotnet/api/system.guid [Char]: https://docs.microsoft.com/en-us/dotnet/api/system.char [String]: https://docs.microsoft.com/en-us/dotnet/api/system.string diff --git a/docs/images/benchmarks/guid-v6.3.0.png b/docs/benchmarks/images/guid-v6.3.0.png similarity index 100% rename from docs/images/benchmarks/guid-v6.3.0.png rename to docs/benchmarks/images/guid-v6.3.0.png diff --git a/docs/images/benchmarks/int32-v6.3.0.png b/docs/benchmarks/images/int32-v6.3.0.png similarity index 100% rename from docs/images/benchmarks/int32-v6.3.0.png rename to docs/benchmarks/images/int32-v6.3.0.png diff --git a/docs/images/benchmarks/v7.2.0.png b/docs/benchmarks/images/v7.2.0.png similarity index 100% rename from docs/images/benchmarks/v7.2.0.png rename to docs/benchmarks/images/v7.2.0.png diff --git a/docs/benchmarks/images/v8.1.0.png b/docs/benchmarks/images/v8.1.0.png new file mode 100644 index 0000000..3f498cf Binary files /dev/null and b/docs/benchmarks/images/v8.1.0.png differ diff --git a/docs/benchmarks/v7.2.0.md b/docs/benchmarks/v7.2.0.md new file mode 100644 index 0000000..934eaa2 --- /dev/null +++ b/docs/benchmarks/v7.2.0.md @@ -0,0 +1,120 @@ +# Benchmarks - Version `7.2.0` + +### Benchmarked Libraries +| Package | Version | +| ------- |:-------:| +| Microsoft.EntityFrameworkCore.SqlServer | 7.0.4 | +| BlazarTech.QueryableValues.SqlServer | 7.2.0 | + +### 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 (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. + +[![Benchmarks Chart][BenchmarksChart]][BenchmarksChartInteractive] + +
+ +| 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 | +| WithJson | Guid | 128 | 665.9 us | 38.37 us | 51.23 us | 636.8 us | 0.13 | 0.01 | - | - | - | 51.12 KB | 0.69 | +| | | | | | | | | | | | | | | +| Without | Guid | 512 | 16,031.0 us | 74.08 us | 98.89 us | 16,023.7 us | 1.00 | 0.00 | - | - | - | 219.5 KB | 1.00 | +| WithXml | Guid | 512 | 2,528.8 us | 38.80 us | 51.79 us | 2,517.7 us | 0.16 | 0.00 | - | - | - | 84.36 KB | 0.38 | +| WithJson | Guid | 512 | 1,368.8 us | 22.42 us | 29.93 us | 1,355.1 us | 0.09 | 0.00 | - | - | - | 80.08 KB | 0.36 | +| | | | | | | | | | | | | | | +| Without | Guid | 2048 | 71,956.6 us | 688.35 us | 918.93 us | 72,148.6 us | 1.00 | 0.00 | - | - | - | 801.13 KB | 1.00 | +| WithXml | Guid | 2048 | 9,399.9 us | 76.33 us | 101.90 us | 9,359.8 us | 0.13 | 0.00 | 5.0000 | 5.0000 | 5.0000 | 213.42 KB | 0.27 | +| WithJson | Guid | 2048 | 4,463.6 us | 36.90 us | 49.26 us | 4,442.6 us | 0.06 | 0.00 | - | - | - | 197.4 KB | 0.25 | +| | | | | | | | | | | | | | | +| Without | String | 2 | 858.7 us | 23.34 us | 31.16 us | 846.2 us | 1.00 | 0.00 | - | - | - | 21.44 KB | 1.00 | +| WithXml | String | 2 | 637.4 us | 35.57 us | 47.48 us | 626.0 us | 0.74 | 0.04 | - | - | - | 55.52 KB | 2.59 | +| WithJson | String | 2 | 534.5 us | 30.81 us | 41.13 us | 528.7 us | 0.62 | 0.03 | - | - | - | 42.83 KB | 2.00 | +| | | | | | | | | | | | | | | +| Without | String | 8 | 1,028.9 us | 24.07 us | 32.13 us | 1,015.2 us | 1.00 | 0.00 | - | - | - | 25.55 KB | 1.00 | +| WithXml | String | 8 | 737.8 us | 44.23 us | 59.05 us | 727.5 us | 0.72 | 0.04 | - | - | - | 56.98 KB | 2.23 | +| WithJson | String | 8 | 641.8 us | 34.63 us | 46.23 us | 640.1 us | 0.62 | 0.04 | - | - | - | 43.64 KB | 1.71 | +| | | | | | | | | | | | | | | +| Without | String | 32 | 1,692.5 us | 23.43 us | 31.27 us | 1,684.7 us | 1.00 | 0.00 | - | - | - | 41.84 KB | 1.00 | +| WithXml | String | 32 | 1,016.7 us | 56.75 us | 75.76 us | 976.6 us | 0.60 | 0.04 | - | - | - | 60.35 KB | 1.44 | +| WithJson | String | 32 | 871.5 us | 39.02 us | 52.10 us | 843.8 us | 0.51 | 0.03 | - | - | - | 47.29 KB | 1.13 | +| | | | | | | | | | | | | | | +| Without | String | 128 | 7,665.5 us | 28.53 us | 38.09 us | 7,662.0 us | 1.00 | 0.00 | - | - | - | 103.65 KB | 1.00 | +| WithXml | String | 128 | 2,392.2 us | 35.64 us | 47.57 us | 2,379.7 us | 0.31 | 0.01 | - | - | - | 74.85 KB | 0.72 | +| WithJson | String | 128 | 2,063.6 us | 26.61 us | 35.53 us | 2,063.5 us | 0.27 | 0.01 | - | - | - | 61.2 KB | 0.59 | +| | | | | | | | | | | | | | | +| Without | String | 512 | 26,444.7 us | 102.44 us | 136.75 us | 26,421.0 us | 1.00 | 0.00 | - | - | - | 343.51 KB | 1.00 | +| WithXml | String | 512 | 8,134.2 us | 32.51 us | 43.41 us | 8,125.8 us | 0.31 | 0.00 | - | - | - | 132.34 KB | 0.39 | +| WithJson | String | 512 | 7,210.9 us | 33.10 us | 44.18 us | 7,199.6 us | 0.27 | 0.00 | - | - | - | 116.42 KB | 0.34 | +| | | | | | | | | | | | | | | +| Without | String | 2048 | 112,512.8 us | 443.78 us | 592.43 us | 112,461.1 us | 1.00 | 0.00 | 5.0000 | - | - | 1310.32 KB | 1.00 | +| WithXml | String | 2048 | 32,080.3 us | 138.18 us | 184.47 us | 32,075.1 us | 0.29 | 0.00 | - | - | - | 361.05 KB | 0.28 | +| WithJson | String | 2048 | 28,929.1 us | 84.67 us | 113.03 us | 28,917.8 us | 0.26 | 0.00 | - | - | - | 336.47 KB | 0.26 | + +
+ + +[BenchmarksChart]: /images/v7.2.0.png +[BenchmarksChartInteractive]: https://chartbenchmark.net/?src=repo#shared=%7B%22results%22%3A%22BenchmarkDotNet%3Dv0.13.5%2C%20OS%3DWindows%2011%20(10.0.22621.1413%2F22H2%2F2022Update%2FSunValley2)%5CnAMD%20Ryzen%209%206900HS%20Creator%20Edition%2C%201%20CPU%2C%2016%20logical%20and%208%20physical%20cores%5Cn.NET%20SDK%3D7.0.202%5Cn%20%20%5BHost%5D%20%20%20%20%20%3A%20.NET%206.0.15%20(6.0.1523.11507)%2C%20X64%20RyuJIT%20AVX2%5Cn%20%20Job-OFVMJD%20%3A%20.NET%206.0.15%20(6.0.1523.11507)%2C%20X64%20RyuJIT%20AVX2%5Cn%5CnServer%3DTrue%20%20InvocationCount%3D200%20%20IterationCount%3D25%5CnRunStrategy%3DMonitoring%20%20UnrollFactor%3D1%20%20WarmupCount%3D1%5Cn%5Cn%7C%20%20%20Method%20%7C%20%20%20Type%20%7C%20NumberOfValues%20%7C%20%20%20%20%20%20%20%20%20Mean%20%7C%20%20%20%20%20Error%20%7C%20%20%20%20StdDev%20%7C%20%20%20%20%20%20%20Median%20%7C%20Ratio%20%7C%20RatioSD%20%7C%20%20%20Gen0%20%7C%20%20%20Gen1%20%7C%20%20%20Gen2%20%7C%20%20Allocated%20%7C%20Alloc%20Ratio%20%7C%5Cn%7C---------%20%7C-------%20%7C---------------%20%7C-------------%3A%7C----------%3A%7C----------%3A%7C-------------%3A%7C------%3A%7C--------%3A%7C-------%3A%7C-------%3A%7C-------%3A%7C-----------%3A%7C------------%3A%7C%5Cn%7C%20%20Without%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%202%20%7C%20%20%20%20%20824.3%20us%20%7C%20%2026.03%20us%20%7C%20%2034.75%20us%20%7C%20%20%20%20%20808.9%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2020.26%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%202%20%7C%20%20%20%20%20508.7%20us%20%7C%20%2032.46%20us%20%7C%20%2043.34%20us%20%7C%20%20%20%20%20504.3%20us%20%7C%20%200.62%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2041.37%20KB%20%7C%20%20%20%20%20%20%20%202.04%20%7C%5Cn%7C%20WithJson%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%202%20%7C%20%20%20%20%20431.7%20us%20%7C%20%2035.52%20us%20%7C%20%2047.41%20us%20%7C%20%20%20%20%20446.8%20us%20%7C%20%200.52%20%7C%20%20%20%200.05%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%2041.5%20KB%20%7C%20%20%20%20%20%20%20%202.05%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%208%20%7C%20%20%20%20%20964.8%20us%20%7C%20%2025.05%20us%20%7C%20%2033.44%20us%20%7C%20%20%20%20%20954.6%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2021.17%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%208%20%7C%20%20%20%20%20548.2%20us%20%7C%20%2034.29%20us%20%7C%20%2045.78%20us%20%7C%20%20%20%20%20537.0%20us%20%7C%20%200.57%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2041.33%20KB%20%7C%20%20%20%20%20%20%20%201.95%20%7C%5Cn%7C%20WithJson%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%208%20%7C%20%20%20%20%20445.1%20us%20%7C%20%2034.28%20us%20%7C%20%2045.76%20us%20%7C%20%20%20%20%20453.6%20us%20%7C%20%200.46%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2041.56%20KB%20%7C%20%20%20%20%20%20%20%201.96%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%2032%20%7C%20%20%201%2C519.3%20us%20%7C%20%2034.23%20us%20%7C%20%2045.69%20us%20%7C%20%20%201%2C494.4%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2025.45%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%2032%20%7C%20%20%20%20%20687.5%20us%20%7C%20%2032.29%20us%20%7C%20%2043.10%20us%20%7C%20%20%20%20%20664.9%20us%20%7C%20%200.45%20%7C%20%20%20%200.03%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2041.52%20KB%20%7C%20%20%20%20%20%20%20%201.63%20%7C%5Cn%7C%20WithJson%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%2032%20%7C%20%20%20%20%20448.1%20us%20%7C%20%2038.22%20us%20%7C%20%2051.03%20us%20%7C%20%20%20%20%20425.9%20us%20%7C%20%200.30%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2041.61%20KB%20%7C%20%20%20%20%20%20%20%201.63%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20128%20%7C%20%20%205%2C470.2%20us%20%7C%20%2025.34%20us%20%7C%20%2033.83%20us%20%7C%20%20%205%2C473.2%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2041.18%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20128%20%7C%20%20%201%2C334.4%20us%20%7C%20%2037.80%20us%20%7C%20%2050.47%20us%20%7C%20%20%201%2C316.5%20us%20%7C%20%200.24%20%7C%20%20%20%200.01%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2044.02%20KB%20%7C%20%20%20%20%20%20%20%201.07%20%7C%5Cn%7C%20WithJson%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20128%20%7C%20%20%20%20%20498.9%20us%20%7C%20%2033.69%20us%20%7C%20%2044.97%20us%20%7C%20%20%20%20%20498.1%20us%20%7C%20%200.09%20%7C%20%20%20%200.01%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2042.53%20KB%20%7C%20%20%20%20%20%20%20%201.03%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20512%20%7C%20%2017%2C572.2%20us%20%7C%20%2068.50%20us%20%7C%20%2091.45%20us%20%7C%20%2017%2C566.4%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20105.67%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20512%20%7C%20%20%204%2C016.2%20us%20%7C%20%2030.74%20us%20%7C%20%2041.04%20us%20%7C%20%20%204%2C014.4%20us%20%7C%20%200.23%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2052.18%20KB%20%7C%20%20%20%20%20%20%20%200.49%20%7C%5Cn%7C%20WithJson%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%20%20512%20%7C%20%20%20%20%20685.0%20us%20%7C%20%2030.40%20us%20%7C%20%2040.59%20us%20%7C%20%20%20%20%20661.9%20us%20%7C%20%200.04%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2046.37%20KB%20%7C%20%20%20%20%20%20%20%200.44%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%202048%20%7C%20%2071%2C616.8%20us%20%7C%20677.00%20us%20%7C%20903.77%20us%20%7C%20%2071%2C227.6%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20363.17%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%202048%20%7C%20%2014%2C045.8%20us%20%7C%20%2050.55%20us%20%7C%20%2067.48%20us%20%7C%20%2014%2C029.9%20us%20%7C%20%200.20%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2084.85%20KB%20%7C%20%20%20%20%20%20%20%200.23%20%7C%5Cn%7C%20WithJson%20%7C%20%20Int32%20%7C%20%20%20%20%20%20%20%20%20%20%202048%20%7C%20%20%201%2C577.1%20us%20%7C%20%2032.17%20us%20%7C%20%2042.95%20us%20%7C%20%20%201%2C564.8%20us%20%7C%20%200.02%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2061.07%20KB%20%7C%20%20%20%20%20%20%20%200.17%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%202%20%7C%20%20%20%20%20788.9%20us%20%7C%20%2020.31%20us%20%7C%20%2027.11%20us%20%7C%20%20%20%20%20778.1%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2020.74%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%202%20%7C%20%20%20%20%20487.6%20us%20%7C%20%2030.51%20us%20%7C%20%2040.74%20us%20%7C%20%20%20%20%20487.7%20us%20%7C%20%200.62%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2041.23%20KB%20%7C%20%20%20%20%20%20%20%201.99%20%7C%5Cn%7C%20WithJson%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%202%20%7C%20%20%20%20%20434.7%20us%20%7C%20%2033.42%20us%20%7C%20%2044.61%20us%20%7C%20%20%20%20%20443.3%20us%20%7C%20%200.55%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2041.19%20KB%20%7C%20%20%20%20%20%20%20%201.99%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%208%20%7C%20%20%20%20%20939.1%20us%20%7C%20%2029.24%20us%20%7C%20%2039.04%20us%20%7C%20%20%20%20%20921.1%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2023.49%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%208%20%7C%20%20%20%20%20515.1%20us%20%7C%20%2032.95%20us%20%7C%20%2043.99%20us%20%7C%20%20%20%20%20509.2%20us%20%7C%20%200.55%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2042.23%20KB%20%7C%20%20%20%20%20%20%20%201.80%20%7C%5Cn%7C%20WithJson%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%208%20%7C%20%20%20%20%20450.0%20us%20%7C%20%2033.55%20us%20%7C%20%2044.79%20us%20%7C%20%20%20%20%20461.4%20us%20%7C%20%200.48%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2041.98%20KB%20%7C%20%20%20%20%20%20%20%201.79%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%2032%20%7C%20%20%201%2C566.2%20us%20%7C%20%2043.12%20us%20%7C%20%2057.56%20us%20%7C%20%20%201%2C551.3%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2033.24%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%2032%20%7C%20%20%20%20%20607.3%20us%20%7C%20%2033.01%20us%20%7C%20%2044.07%20us%20%7C%20%20%20%20%20587.0%20us%20%7C%20%200.39%20%7C%20%20%20%200.03%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2043.58%20KB%20%7C%20%20%20%20%20%20%20%201.31%20%7C%5Cn%7C%20WithJson%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%2032%20%7C%20%20%20%20%20488.4%20us%20%7C%20%2032.86%20us%20%7C%20%2043.87%20us%20%7C%20%20%20%20%20487.3%20us%20%7C%20%200.31%20%7C%20%20%20%200.03%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2043.48%20KB%20%7C%20%20%20%20%20%20%20%201.31%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20128%20%7C%20%20%205%2C140.0%20us%20%7C%20%2052.22%20us%20%7C%20%2069.71%20us%20%7C%20%20%205%2C138.2%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2074.11%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20128%20%7C%20%20%20%20%20987.8%20us%20%7C%20%2037.30%20us%20%7C%20%2049.79%20us%20%7C%20%20%20%20%20965.0%20us%20%7C%20%200.19%20%7C%20%20%20%200.01%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2051.97%20KB%20%7C%20%20%20%20%20%20%20%200.70%20%7C%5Cn%7C%20WithJson%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20128%20%7C%20%20%20%20%20665.9%20us%20%7C%20%2038.37%20us%20%7C%20%2051.23%20us%20%7C%20%20%20%20%20636.8%20us%20%7C%20%200.13%20%7C%20%20%20%200.01%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2051.12%20KB%20%7C%20%20%20%20%20%20%20%200.69%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20512%20%7C%20%2016%2C031.0%20us%20%7C%20%2074.08%20us%20%7C%20%2098.89%20us%20%7C%20%2016%2C023.7%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20219.5%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20512%20%7C%20%20%202%2C528.8%20us%20%7C%20%2038.80%20us%20%7C%20%2051.79%20us%20%7C%20%20%202%2C517.7%20us%20%7C%20%200.16%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2084.36%20KB%20%7C%20%20%20%20%20%20%20%200.38%20%7C%5Cn%7C%20WithJson%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%20%20512%20%7C%20%20%201%2C368.8%20us%20%7C%20%2022.42%20us%20%7C%20%2029.93%20us%20%7C%20%20%201%2C355.1%20us%20%7C%20%200.09%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2080.08%20KB%20%7C%20%20%20%20%20%20%20%200.36%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%202048%20%7C%20%2071%2C956.6%20us%20%7C%20688.35%20us%20%7C%20918.93%20us%20%7C%20%2072%2C148.6%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20801.13%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%202048%20%7C%20%20%209%2C399.9%20us%20%7C%20%2076.33%20us%20%7C%20101.90%20us%20%7C%20%20%209%2C359.8%20us%20%7C%20%200.13%20%7C%20%20%20%200.00%20%7C%205.0000%20%7C%205.0000%20%7C%205.0000%20%7C%20%20213.42%20KB%20%7C%20%20%20%20%20%20%20%200.27%20%7C%5Cn%7C%20WithJson%20%7C%20%20%20Guid%20%7C%20%20%20%20%20%20%20%20%20%20%202048%20%7C%20%20%204%2C463.6%20us%20%7C%20%2036.90%20us%20%7C%20%2049.26%20us%20%7C%20%20%204%2C442.6%20us%20%7C%20%200.06%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20197.4%20KB%20%7C%20%20%20%20%20%20%20%200.25%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%202%20%7C%20%20%20%20%20858.7%20us%20%7C%20%2023.34%20us%20%7C%20%2031.16%20us%20%7C%20%20%20%20%20846.2%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2021.44%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%202%20%7C%20%20%20%20%20637.4%20us%20%7C%20%2035.57%20us%20%7C%20%2047.48%20us%20%7C%20%20%20%20%20626.0%20us%20%7C%20%200.74%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2055.52%20KB%20%7C%20%20%20%20%20%20%20%202.59%20%7C%5Cn%7C%20WithJson%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%202%20%7C%20%20%20%20%20534.5%20us%20%7C%20%2030.81%20us%20%7C%20%2041.13%20us%20%7C%20%20%20%20%20528.7%20us%20%7C%20%200.62%20%7C%20%20%20%200.03%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2042.83%20KB%20%7C%20%20%20%20%20%20%20%202.00%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%208%20%7C%20%20%201%2C028.9%20us%20%7C%20%2024.07%20us%20%7C%20%2032.13%20us%20%7C%20%20%201%2C015.2%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2025.55%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%208%20%7C%20%20%20%20%20737.8%20us%20%7C%20%2044.23%20us%20%7C%20%2059.05%20us%20%7C%20%20%20%20%20727.5%20us%20%7C%20%200.72%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2056.98%20KB%20%7C%20%20%20%20%20%20%20%202.23%20%7C%5Cn%7C%20WithJson%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%208%20%7C%20%20%20%20%20641.8%20us%20%7C%20%2034.63%20us%20%7C%20%2046.23%20us%20%7C%20%20%20%20%20640.1%20us%20%7C%20%200.62%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2043.64%20KB%20%7C%20%20%20%20%20%20%20%201.71%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%2032%20%7C%20%20%201%2C692.5%20us%20%7C%20%2023.43%20us%20%7C%20%2031.27%20us%20%7C%20%20%201%2C684.7%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2041.84%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%2032%20%7C%20%20%201%2C016.7%20us%20%7C%20%2056.75%20us%20%7C%20%2075.76%20us%20%7C%20%20%20%20%20976.6%20us%20%7C%20%200.60%20%7C%20%20%20%200.04%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2060.35%20KB%20%7C%20%20%20%20%20%20%20%201.44%20%7C%5Cn%7C%20WithJson%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%2032%20%7C%20%20%20%20%20871.5%20us%20%7C%20%2039.02%20us%20%7C%20%2052.10%20us%20%7C%20%20%20%20%20843.8%20us%20%7C%20%200.51%20%7C%20%20%20%200.03%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2047.29%20KB%20%7C%20%20%20%20%20%20%20%201.13%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20128%20%7C%20%20%207%2C665.5%20us%20%7C%20%2028.53%20us%20%7C%20%2038.09%20us%20%7C%20%20%207%2C662.0%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20103.65%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20128%20%7C%20%20%202%2C392.2%20us%20%7C%20%2035.64%20us%20%7C%20%2047.57%20us%20%7C%20%20%202%2C379.7%20us%20%7C%20%200.31%20%7C%20%20%20%200.01%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%2074.85%20KB%20%7C%20%20%20%20%20%20%20%200.72%20%7C%5Cn%7C%20WithJson%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20128%20%7C%20%20%202%2C063.6%20us%20%7C%20%2026.61%20us%20%7C%20%2035.53%20us%20%7C%20%20%202%2C063.5%20us%20%7C%20%200.27%20%7C%20%20%20%200.01%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%2061.2%20KB%20%7C%20%20%20%20%20%20%20%200.59%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20512%20%7C%20%2026%2C444.7%20us%20%7C%20102.44%20us%20%7C%20136.75%20us%20%7C%20%2026%2C421.0%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20343.51%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20512%20%7C%20%20%208%2C134.2%20us%20%7C%20%2032.51%20us%20%7C%20%2043.41%20us%20%7C%20%20%208%2C125.8%20us%20%7C%20%200.31%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20132.34%20KB%20%7C%20%20%20%20%20%20%20%200.39%20%7C%5Cn%7C%20WithJson%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%20%20512%20%7C%20%20%207%2C210.9%20us%20%7C%20%2033.10%20us%20%7C%20%2044.18%20us%20%7C%20%20%207%2C199.6%20us%20%7C%20%200.27%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20116.42%20KB%20%7C%20%20%20%20%20%20%20%200.34%20%7C%5Cn%7C%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%5Cn%7C%20%20Without%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%202048%20%7C%20112%2C512.8%20us%20%7C%20443.78%20us%20%7C%20592.43%20us%20%7C%20112%2C461.1%20us%20%7C%20%201.00%20%7C%20%20%20%200.00%20%7C%205.0000%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%201310.32%20KB%20%7C%20%20%20%20%20%20%20%201.00%20%7C%5Cn%7C%20%20WithXml%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%202048%20%7C%20%2032%2C080.3%20us%20%7C%20138.18%20us%20%7C%20184.47%20us%20%7C%20%2032%2C075.1%20us%20%7C%20%200.29%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20361.05%20KB%20%7C%20%20%20%20%20%20%20%200.28%20%7C%5Cn%7C%20WithJson%20%7C%20String%20%7C%20%20%20%20%20%20%20%20%20%20%202048%20%7C%20%2028%2C929.1%20us%20%7C%20%2084.67%20us%20%7C%20113.03%20us%20%7C%20%2028%2C917.8%20us%20%7C%20%200.26%20%7C%20%20%20%200.00%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20%20%20%20%20-%20%7C%20%20336.47%20KB%20%7C%20%20%20%20%20%20%20%200.26%20%7C%5Cn%22%2C%22settings%22%3A%7B%22display%22%3A%22Duration%22%2C%22scale%22%3A%22Log2%22%2C%22theme%22%3A%22Dark%22%7D%7D "Click for interactive chart" \ No newline at end of file diff --git a/src/QueryableValues.SqlServer.EFCore3/QueryableValues.SqlServer.EFCore3.csproj b/src/QueryableValues.SqlServer.EFCore3/QueryableValues.SqlServer.EFCore3.csproj index 9f1f21f..743ed09 100644 --- a/src/QueryableValues.SqlServer.EFCore3/QueryableValues.SqlServer.EFCore3.csproj +++ b/src/QueryableValues.SqlServer.EFCore3/QueryableValues.SqlServer.EFCore3.csproj @@ -1,16 +1,21 @@ ο»Ώ - - + + - - $(VersionEFCore3) - netstandard2.0;net6.0 - 9.0 - Debug;Release;Test - $(DefineConstants);EFCORE;EFCORE3 - - - - - + + $(VersionEFCore3) + netstandard2.0;net6.0 + 9.0 + Debug;Release;Test + $(DefineConstants);EFCORE;EFCORE3 + + + + + + + + + + diff --git a/src/QueryableValues.SqlServer.EFCore5/QueryableValues.SqlServer.EFCore5.csproj b/src/QueryableValues.SqlServer.EFCore5/QueryableValues.SqlServer.EFCore5.csproj index 48b6000..b0dbc03 100644 --- a/src/QueryableValues.SqlServer.EFCore5/QueryableValues.SqlServer.EFCore5.csproj +++ b/src/QueryableValues.SqlServer.EFCore5/QueryableValues.SqlServer.EFCore5.csproj @@ -1,16 +1,21 @@ ο»Ώ - - - - - $(VersionEFCore5) - netstandard2.1;net6.0 - 9.0 - Debug;Release;Test - $(DefineConstants);EFCORE;EFCORE5 - - - - - + + + + + $(VersionEFCore5) + netstandard2.1;net6.0 + 9.0 + Debug;Release;Test + $(DefineConstants);EFCORE;EFCORE5 + + + + + + + + + + diff --git a/src/QueryableValues.SqlServer.EFCore6/QueryableValues.SqlServer.EFCore6.csproj b/src/QueryableValues.SqlServer.EFCore6/QueryableValues.SqlServer.EFCore6.csproj index 9663a6d..a6ca78a 100644 --- a/src/QueryableValues.SqlServer.EFCore6/QueryableValues.SqlServer.EFCore6.csproj +++ b/src/QueryableValues.SqlServer.EFCore6/QueryableValues.SqlServer.EFCore6.csproj @@ -10,6 +10,7 @@ + diff --git a/src/QueryableValues.SqlServer.EFCore7/QueryableValues.SqlServer.EFCore7.csproj b/src/QueryableValues.SqlServer.EFCore7/QueryableValues.SqlServer.EFCore7.csproj index 559ec6c..65bbe40 100644 --- a/src/QueryableValues.SqlServer.EFCore7/QueryableValues.SqlServer.EFCore7.csproj +++ b/src/QueryableValues.SqlServer.EFCore7/QueryableValues.SqlServer.EFCore7.csproj @@ -1,15 +1,16 @@ ο»Ώ - - - - - $(VersionEFCore7) - net6.0 - Debug;Release;Test - $(DefineConstants);EFCORE;EFCORE7 - + + - - - + + $(VersionEFCore7) + net6.0 + Debug;Release;Test + $(DefineConstants);EFCORE;EFCORE7 + + + + + + diff --git a/src/QueryableValues.SqlServer.EFCore8/QueryableValues.SqlServer.EFCore8.csproj b/src/QueryableValues.SqlServer.EFCore8/QueryableValues.SqlServer.EFCore8.csproj index 1a11106..c44b98d 100644 --- a/src/QueryableValues.SqlServer.EFCore8/QueryableValues.SqlServer.EFCore8.csproj +++ b/src/QueryableValues.SqlServer.EFCore8/QueryableValues.SqlServer.EFCore8.csproj @@ -1,15 +1,16 @@ ο»Ώ - - - - - $(VersionEFCore8) - net8.0 - Debug;Release;Test - $(DefineConstants);EFCORE;EFCORE8 - + + - - - + + $(VersionEFCore8) + net8.0 + Debug;Release;Test + $(DefineConstants);EFCORE;EFCORE8 + + + + + + diff --git a/src/QueryableValues.SqlServer/DeferredValues.cs b/src/QueryableValues.SqlServer/DeferredValues.cs index e81af1b..aa674a7 100644 --- a/src/QueryableValues.SqlServer/DeferredValues.cs +++ b/src/QueryableValues.SqlServer/DeferredValues.cs @@ -4,9 +4,10 @@ namespace BlazarTech.QueryableValues { - internal sealed class DeferredValues : IDeferredValues + internal sealed class DeferredValues : IDeferredValues where T : notnull where T2 : notnull + where TEntity : QueryableValuesEntity { private readonly ISerializer _serializer; private readonly ValuesWrapper _valuesWrapper; @@ -25,7 +26,7 @@ public DeferredValues(ISerializer serializer, ValuesWrapper valuesWrapper { _serializer = serializer; _valuesWrapper = valuesWrapper; - Mappings = EntityPropertyMapping.GetMappings(); + Mappings = EntityPropertyMapping.GetMappings(); } public string ToString(IFormatProvider? provider) => _serializer.Serialize(_valuesWrapper.ProjectedValues, Mappings); diff --git a/src/QueryableValues.SqlServer/EntityPropertyMapping.cs b/src/QueryableValues.SqlServer/EntityPropertyMapping.cs index 1155210..524920d 100644 --- a/src/QueryableValues.SqlServer/EntityPropertyMapping.cs +++ b/src/QueryableValues.SqlServer/EntityPropertyMapping.cs @@ -10,8 +10,8 @@ internal sealed class EntityPropertyMapping { internal static readonly IReadOnlyDictionary SimpleTypes; - private static readonly PropertyInfo[] EntityProperties = typeof(QueryableValuesEntity).GetProperties().Where(i => i.Name != QueryableValuesEntity.IndexPropertyName).ToArray(); - private static readonly ConcurrentDictionary> MappingCache = new ConcurrentDictionary>(); + private static readonly ConcurrentDictionary> TargetTypePropertyCache = new ConcurrentDictionary>(); + private static readonly ConcurrentDictionary<(Type, Type), IReadOnlyList> MappingCache = new ConcurrentDictionary<(Type, Type), IReadOnlyList>(); public PropertyInfo Source { get; } public PropertyInfo Target { get; } @@ -35,7 +35,11 @@ static EntityPropertyMapping() { typeof(DateTimeOffset), EntityPropertyTypeName.DateTimeOffset }, { typeof(Guid), EntityPropertyTypeName.Guid }, { typeof(char), EntityPropertyTypeName.Char }, - { typeof(string), EntityPropertyTypeName.String } + { typeof(string), EntityPropertyTypeName.String }, +#if EFCORE8 + { typeof(DateOnly), EntityPropertyTypeName.DateOnly }, + { typeof(TimeOnly), EntityPropertyTypeName.TimeOnly } +#endif }; } @@ -87,9 +91,33 @@ public static bool IsSimpleType(Type type) return SimpleTypes.ContainsKey(normalizedType); } - public static IReadOnlyList GetMappings(Type sourceType) + private static IReadOnlyList GetTargetTypeProperties(Type targetType) { - if (MappingCache.TryGetValue(sourceType, out IReadOnlyList? mappingsFromCache)) + if (TargetTypePropertyCache.TryGetValue(targetType, out IReadOnlyList? properties)) + { + return properties; + } + + if (!typeof(QueryableValuesEntity).IsAssignableFrom(targetType)) + { + throw new InvalidOperationException(); + } + + properties = targetType + .GetProperties() + .Where(i => i.Name != QueryableValuesEntity.IndexPropertyName) + .ToArray(); + + TargetTypePropertyCache.TryAdd(targetType, properties); + + return properties; + } + + public static IReadOnlyList GetMappings(Type sourceType, Type targetType) + { + var mappingCacheKey = (sourceType, targetType); + + if (MappingCache.TryGetValue(mappingCacheKey, out IReadOnlyList? mappingsFromCache)) { return mappingsFromCache; } @@ -104,7 +132,7 @@ public static IReadOnlyList GetMappings(Type sourceType) var mappings = new List(sourceProperties.Length); var targetPropertiesByType = ( - from i in EntityProperties + from i in GetTargetTypeProperties(targetType) group i by GetNormalizedType(i.PropertyType) into g select g ) @@ -136,14 +164,15 @@ select g } } - MappingCache.TryAdd(sourceType, mappings); + MappingCache.TryAdd(mappingCacheKey, mappings); return mappings; } - public static IReadOnlyList GetMappings() + public static IReadOnlyList GetMappings() + where TTargetEntity : QueryableValuesEntity { - return GetMappings(typeof(T)); + return GetMappings(typeof(TSource), typeof(TTargetEntity)); } public object? GetSourceNormalizedValue(object objectInstance) diff --git a/src/QueryableValues.SqlServer/EntityPropertyTypeName.cs b/src/QueryableValues.SqlServer/EntityPropertyTypeName.cs index 4111970..436606a 100644 --- a/src/QueryableValues.SqlServer/EntityPropertyTypeName.cs +++ b/src/QueryableValues.SqlServer/EntityPropertyTypeName.cs @@ -15,6 +15,10 @@ internal enum EntityPropertyTypeName DateTimeOffset, Guid, Char, - String + String, +#if EFCORE8 + DateOnly, + TimeOnly +#endif } } \ No newline at end of file diff --git a/src/QueryableValues.SqlServer/IQueryableFactory.cs b/src/QueryableValues.SqlServer/IQueryableFactory.cs index 50055bf..1573b45 100644 --- a/src/QueryableValues.SqlServer/IQueryableFactory.cs +++ b/src/QueryableValues.SqlServer/IQueryableFactory.cs @@ -24,5 +24,10 @@ public IQueryable Create(DbContext dbContext, IEnumerable v where TEnum : struct, Enum; IQueryable Create(DbContext dbContext, IEnumerable values, Action>? configure) where TSource : notnull; + +#if EFCORE8 + IQueryable Create(DbContext dbContext, IEnumerable values); + IQueryable Create(DbContext dbContext, IEnumerable values); +#endif } } diff --git a/src/QueryableValues.SqlServer/ModelCustomizer.cs b/src/QueryableValues.SqlServer/ModelCustomizer.cs index fb5dd19..c974fe9 100644 --- a/src/QueryableValues.SqlServer/ModelCustomizer.cs +++ b/src/QueryableValues.SqlServer/ModelCustomizer.cs @@ -2,6 +2,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using System; namespace BlazarTech.QueryableValues { @@ -27,33 +28,55 @@ private static void SetDefaultPrecision(PropertyBuilder property) #endif } - private static void SetupEntity(ModelBuilder modelBuilder) + private static void SetupEntity(ModelBuilder modelBuilder, Action>? buildAction = null) + where TEntity : QueryableValuesEntity { modelBuilder - .Entity(entity => + .Entity(entity => { - SetDefaultPrecision(entity.Property(p => p.M)); - SetDefaultPrecision(entity.Property(p => p.M1)); - SetDefaultPrecision(entity.Property(p => p.M2)); - SetDefaultPrecision(entity.Property(p => p.M3)); - SetDefaultPrecision(entity.Property(p => p.M4)); - SetDefaultPrecision(entity.Property(p => p.M5)); - SetDefaultPrecision(entity.Property(p => p.M6)); - SetDefaultPrecision(entity.Property(p => p.M7)); - SetDefaultPrecision(entity.Property(p => p.M8)); - SetDefaultPrecision(entity.Property(p => p.M9)); + buildAction?.Invoke(entity); // By mapping to a fake view, we stop EF from including these entities during // SQL generation in migrations and by the Create and Drop apis in DbContext.Database. entity - .ToView(nameof(QueryableValuesEntity)) + .ToView(Guid.NewGuid().ToString()) .HasKey(i => i.X); }); } public void Customize(ModelBuilder modelBuilder, DbContext context) { - SetupEntity(modelBuilder); + SetupEntity(modelBuilder, entity => + { + SetDefaultPrecision(entity.Property(p => p.M)); + SetDefaultPrecision(entity.Property(p => p.M1)); + SetDefaultPrecision(entity.Property(p => p.M2)); + SetDefaultPrecision(entity.Property(p => p.M3)); + SetDefaultPrecision(entity.Property(p => p.M4)); + SetDefaultPrecision(entity.Property(p => p.M5)); + SetDefaultPrecision(entity.Property(p => p.M6)); + SetDefaultPrecision(entity.Property(p => p.M7)); + SetDefaultPrecision(entity.Property(p => p.M8)); + SetDefaultPrecision(entity.Property(p => p.M9)); + }); + + SetupEntity>(modelBuilder); + SetupEntity>(modelBuilder); + SetupEntity>(modelBuilder); + SetupEntity>(modelBuilder); + SetupEntity>(modelBuilder, entity => SetDefaultPrecision(entity.Property(p => p.V))); + SetupEntity>(modelBuilder); + SetupEntity>(modelBuilder); + SetupEntity>(modelBuilder); + SetupEntity>(modelBuilder); + SetupEntity>(modelBuilder); + SetupEntity>(modelBuilder); + SetupEntity>(modelBuilder); + +#if EFCORE8 + SetupEntity>(modelBuilder); + SetupEntity>(modelBuilder); +#endif _previousModelCustomizer.Customize(modelBuilder, context); } diff --git a/src/QueryableValues.SqlServer/QueryableValuesDbContextExtensions.cs b/src/QueryableValues.SqlServer/QueryableValuesDbContextExtensions.cs index 5ff7f36..7eed436 100644 --- a/src/QueryableValues.SqlServer/QueryableValuesDbContextExtensions.cs +++ b/src/QueryableValues.SqlServer/QueryableValuesDbContextExtensions.cs @@ -262,5 +262,35 @@ public static IQueryable AsQueryableValues(this DbContext dbCo ValidateParameters(dbContext, values); return GetQueryableFactory(dbContext).Create(dbContext, values, configure); } + +#if EFCORE8 + /// + /// Allows an IEnumerable<DateOnly> to be composed in an Entity Framework query. + /// + /// The owning the query. + /// The sequence of values to compose. + /// An IQueryable<DateOnly> that can be composed with other entities in the query. + /// + /// + public static IQueryable AsQueryableValues(this DbContext dbContext, IEnumerable values) + { + ValidateParameters(dbContext, values); + return GetQueryableFactory(dbContext).Create(dbContext, values); + } + + /// + /// Allows an IEnumerable<TimeOnly> to be composed in an Entity Framework query. + /// + /// The owning the query. + /// The sequence of values to compose. + /// An IQueryable<TimeOnly> that can be composed with other entities in the query. + /// + /// + public static IQueryable AsQueryableValues(this DbContext dbContext, IEnumerable values) + { + ValidateParameters(dbContext, values); + return GetQueryableFactory(dbContext).Create(dbContext, values); + } +#endif } } diff --git a/src/QueryableValues.SqlServer/QueryableValuesEnabledDbContextExtensions.cs b/src/QueryableValues.SqlServer/QueryableValuesEnabledDbContextExtensions.cs index 3fd084f..e2baac2 100644 --- a/src/QueryableValues.SqlServer/QueryableValuesEnabledDbContextExtensions.cs +++ b/src/QueryableValues.SqlServer/QueryableValuesEnabledDbContextExtensions.cs @@ -229,5 +229,35 @@ public static IQueryable AsQueryableValues(this IQueryableValu { return GetDbContext(dbContext).AsQueryableValues(values, configure); } + +#if EFCORE8 + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static IQueryable AsQueryableValues(this IQueryableValuesEnabledDbContext dbContext, IEnumerable values) + { + return GetDbContext(dbContext).AsQueryableValues(values); + } + + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static IQueryable AsQueryableValues(this IQueryableValuesEnabledDbContext dbContext, IEnumerable values) + { + return GetDbContext(dbContext).AsQueryableValues(values); + } +#endif } } diff --git a/src/QueryableValues.SqlServer/QueryableValuesEntity.cs b/src/QueryableValues.SqlServer/QueryableValuesEntity.cs index e2fed56..4fb5d33 100644 --- a/src/QueryableValues.SqlServer/QueryableValuesEntity.cs +++ b/src/QueryableValues.SqlServer/QueryableValuesEntity.cs @@ -4,19 +4,27 @@ namespace BlazarTech.QueryableValues { - internal class QueryableValuesEntity + internal abstract class QueryableValuesEntity { - private static readonly IReadOnlyList DataPropertyNames; - public const string IndexPropertyName = nameof(X); - static QueryableValuesEntity() + public int X { get; set; } + } + + internal class SimpleQueryableValuesEntity : QueryableValuesEntity + { + public T? V { get; set; } + } + + internal class ComplexQueryableValuesEntity : QueryableValuesEntity + { + private static readonly IReadOnlyList DataPropertyNames; + + static ComplexQueryableValuesEntity() { DataPropertyNames = GetDataPropertyNames(); } - public int X { get; set; } - public int? I { get; set; } public int? I1 { get; set; } public int? I2 { get; set; } @@ -160,9 +168,33 @@ static QueryableValuesEntity() public char? C8 { get; set; } public char? C9 { get; set; } +#if EFCORE8 + public DateOnly? J { get; set; } + public DateOnly? J1 { get; set; } + public DateOnly? J2 { get; set; } + public DateOnly? J3 { get; set; } + public DateOnly? J4 { get; set; } + public DateOnly? J5 { get; set; } + public DateOnly? J6 { get; set; } + public DateOnly? J7 { get; set; } + public DateOnly? J8 { get; set; } + public DateOnly? J9 { get; set; } + + public TimeOnly? T { get; set; } + public TimeOnly? T1 { get; set; } + public TimeOnly? T2 { get; set; } + public TimeOnly? T3 { get; set; } + public TimeOnly? T4 { get; set; } + public TimeOnly? T5 { get; set; } + public TimeOnly? T6 { get; set; } + public TimeOnly? T7 { get; set; } + public TimeOnly? T8 { get; set; } + public TimeOnly? T9 { get; set; } +#endif + private static List GetDataPropertyNames() { - var properties = typeof(QueryableValuesEntity).GetProperties(); + var properties = typeof(ComplexQueryableValuesEntity).GetProperties(); var result = new List(properties.Length); foreach (var property in properties) diff --git a/src/QueryableValues.SqlServer/Serializers/JsonSerializer.cs b/src/QueryableValues.SqlServer/Serializers/JsonSerializer.cs index cd53d63..fdab45b 100644 --- a/src/QueryableValues.SqlServer/Serializers/JsonSerializer.cs +++ b/src/QueryableValues.SqlServer/Serializers/JsonSerializer.cs @@ -2,6 +2,7 @@ using System; using System.Buffers; using System.Collections.Generic; +using System.Diagnostics; using System.Text; using System.Text.Json; @@ -113,6 +114,24 @@ private sealed class PropertyWriter private static readonly Action WriteGuid = (Utf8JsonWriter writer, Guid value) => writer.WriteStringValue(value); private static readonly Action WriteChar = (Utf8JsonWriter writer, char value) => writer.WriteStringValue(stackalloc[] { value }); +#if EFCORE8 + private static readonly Action WriteDateOnly = (Utf8JsonWriter writer, DateOnly value) => + { + Span buffer = stackalloc char[10]; + value.TryFormat(buffer, out var charsWritten, "o"); + Debug.Assert(charsWritten == buffer.Length); + writer.WriteStringValue(buffer); + }; + + private static readonly Action WriteTimeOnly = (Utf8JsonWriter writer, TimeOnly value) => + { + Span buffer = stackalloc char[16]; + value.TryFormat(buffer, out var charsWritten, "o"); + Debug.Assert(charsWritten == buffer.Length); + writer.WriteStringValue(buffer); + }; +#endif + private readonly string _targetName; private readonly Action? _writeValue; @@ -139,6 +158,10 @@ public PropertyWriter(EntityPropertyMapping mapping) EntityPropertyTypeName.Guid => (writer, value) => WriteAttribute(writer, (Guid?)value, WriteGuid), EntityPropertyTypeName.Char => (writer, value) => WriteAttribute(writer, (char?)value, WriteChar), EntityPropertyTypeName.String => (writer, value) => WriteStringAttribute(writer, (string?)value), +#if EFCORE8 + EntityPropertyTypeName.DateOnly => (writer, value) => WriteAttribute(writer, (DateOnly?)value, WriteDateOnly), + EntityPropertyTypeName.TimeOnly => (writer, value) => WriteAttribute(writer, (TimeOnly?)value, WriteTimeOnly), +#endif _ => throw new NotImplementedException(mapping.TypeName.ToString()), }; } diff --git a/src/QueryableValues.SqlServer/Serializers/XmlSerializer.cs b/src/QueryableValues.SqlServer/Serializers/XmlSerializer.cs index 11de796..8b9d817 100644 --- a/src/QueryableValues.SqlServer/Serializers/XmlSerializer.cs +++ b/src/QueryableValues.SqlServer/Serializers/XmlSerializer.cs @@ -186,6 +186,10 @@ private sealed class PropertyWriter private static readonly Action WriteGuid = (XmlWriter writer, Guid value) => writer.WriteValue(value.ToString()); private static readonly Action WriteChar = (XmlWriter writer, char value) => XmlSerializer.WriteValue(writer, new[] { value }, 1); private static readonly Action WriteString = (XmlWriter writer, string value) => XmlSerializer.WriteValue(writer, value.ToCharArray(), value.Length); +#if EFCORE8 + private static readonly Action WriteDateOnly = (XmlWriter writer, DateOnly value) => writer.WriteValue(value.ToString("o")); + private static readonly Action WriteTimeOnly = (XmlWriter writer, TimeOnly value) => writer.WriteValue(value.ToString("o")); +#endif private readonly string _targetName; private readonly Action? _writeValue; @@ -213,6 +217,10 @@ public PropertyWriter(EntityPropertyMapping mapping) EntityPropertyTypeName.Guid => (writer, value) => WriteAttribute(writer, (Guid?)value, WriteGuid), EntityPropertyTypeName.Char => (writer, value) => WriteAttribute(writer, (char?)value, WriteChar), EntityPropertyTypeName.String => (writer, value) => WriteStringAttribute(writer, (string?)value), +#if EFCORE8 + EntityPropertyTypeName.DateOnly => (writer, value) => WriteAttribute(writer, (DateOnly?)value, WriteDateOnly), + EntityPropertyTypeName.TimeOnly => (writer, value) => WriteAttribute(writer, (TimeOnly?)value, WriteTimeOnly), +#endif _ => throw new NotImplementedException(mapping.TypeName.ToString()), }; } diff --git a/src/QueryableValues.SqlServer/SqlServer/JsonQueryableFactory.cs b/src/QueryableValues.SqlServer/SqlServer/JsonQueryableFactory.cs index 1e4ae05..fddf22f 100644 --- a/src/QueryableValues.SqlServer/SqlServer/JsonQueryableFactory.cs +++ b/src/QueryableValues.SqlServer/SqlServer/JsonQueryableFactory.cs @@ -21,7 +21,7 @@ protected override SqlParameter GetValuesParameter() return new SqlParameter(null, SqlDbType.NVarChar, -1); } - protected override string GetSqlForComplexTypes(IEntityOptionsBuilder entityOptions, bool useSelectTopOptimization, IReadOnlyList mappings) + protected override string GetSql(IEntityOptionsBuilder entityOptions, bool useSelectTopOptimization, IReadOnlyList mappings) { var sb = StringBuilderPool.Get(); @@ -43,9 +43,16 @@ protected override string GetSqlForComplexTypes(IEntityOptionsBuilder entityOpti sb.Append(", [").Append(mapping.Target.Name).Append(']'); } - foreach (var unmappedPropertyName in QueryableValuesEntity.GetUnmappedPropertyNames(mappings)) + if (typeof(TEntity) == typeof(ComplexQueryableValuesEntity)) { - sb.Append(", NULL[").Append(unmappedPropertyName).Append(']'); + // This is necessary because, in some cases, EF will render all the properties of TEntity + // in the outer parts of the query, regardless of the number of properties that were actually projected. + // This behavior was introduced in EF7+. + // See JoinWithProjection test for an example. + foreach (var unmappedPropertyName in ComplexQueryableValuesEntity.GetUnmappedPropertyNames(mappings)) + { + sb.Append(", NULL[").Append(unmappedPropertyName).Append(']'); + } } sb.AppendLine(); @@ -119,6 +126,14 @@ protected override string GetSqlForComplexTypes(IEntityOptionsBuilder entityOpti sb.Append("varchar(max)"); } break; +#if EFCORE8 + case EntityPropertyTypeName.DateOnly: + sb.Append("date"); + break; + case EntityPropertyTypeName.TimeOnly: + sb.Append("time"); + break; +#endif default: throw new NotImplementedException(mapping.TypeName.ToString()); } diff --git a/src/QueryableValues.SqlServer/SqlServer/QueryableFactory.cs b/src/QueryableValues.SqlServer/SqlServer/QueryableFactory.cs index 0b2605e..dfcfe19 100644 --- a/src/QueryableValues.SqlServer/SqlServer/QueryableFactory.cs +++ b/src/QueryableValues.SqlServer/SqlServer/QueryableFactory.cs @@ -122,21 +122,23 @@ private SqlParameter[] GetSqlParameters(IDeferredValues deferredValues) return sqlParameters; } - protected abstract string GetSqlForComplexTypes( + protected abstract string GetSql( IEntityOptionsBuilder entityOptions, bool useSelectTopOptimization, IReadOnlyList mappings - ); + ) + where TEntity : QueryableValuesEntity; - private IQueryable CreateForComplexType(DbContext dbContext, IDeferredValues deferredValues, Action>? configure) + private IQueryable CreateFor(DbContext dbContext, IDeferredValues deferredValues, Action>? configure) where TSource : notnull + where TEntity : QueryableValuesEntity { var useSelectTopOptimization = UseSelectTopOptimization(deferredValues); var sql = getSql(deferredValues.Mappings, configure, useSelectTopOptimization); var sqlParameters = GetSqlParameters(deferredValues); var source = dbContext - .Set() + .Set() .FromSqlRaw(sql, sqlParameters); var projected = projectQueryable(source, deferredValues.Mappings); @@ -171,14 +173,14 @@ string getSql(IReadOnlyList mappings, Action(entityOptions, useSelectTopOptimization, mappings); SqlCache.TryAdd(cacheKey, sql); return sql; } - static IQueryable projectQueryable(IQueryable source, IReadOnlyList mappings) + static IQueryable projectQueryable(IQueryable source, IReadOnlyList mappings) { Type sourceType = typeof(TSource); @@ -189,7 +191,7 @@ static IQueryable projectQueryable(IQueryable so } Expression body; - var parameterExpression = Expression.Parameter(typeof(QueryableValuesEntity), "i"); + var parameterExpression = Expression.Parameter(typeof(TEntity), "i"); var useConstructor = !mappings.All(i => i.Source.CanWrite); @@ -254,7 +256,7 @@ static IQueryable projectQueryable(IQueryable so parameterExpression }; - var selector = Expression.Lambda>(body, bodyParameteters); + var selector = Expression.Lambda>(body, bodyParameteters); SelectorExpressionCache.TryAdd(sourceType, selector); @@ -278,11 +280,11 @@ static Expression getTargetPropertyExpression(ParameterExpression parameterExpre } } - static IQueryable? getFromCache(Type sourceType, IQueryable source) + static IQueryable? getFromCache(Type sourceType, IQueryable source) { if (SelectorExpressionCache.TryGetValue(sourceType, out object? selectorFromCache)) { - var selector = (Expression>)selectorFromCache; + var selector = (Expression>)selectorFromCache; var queryable = Queryable.Select(source, selector); return queryable; } @@ -304,9 +306,9 @@ private IQueryable CreateForSimpleType(DbContext dbContext, IE values.Select(i => new SimpleTypeValue { V = i }) ); - var deferredValues = new DeferredValues>(_serializer, wrappedValues); + var deferredValues = new DeferredValues, SimpleQueryableValuesEntity>(_serializer, wrappedValues); - return CreateForComplexType( + return CreateFor, SimpleQueryableValuesEntity>( dbContext, deferredValues, configure: configure @@ -402,6 +404,18 @@ public IQueryable Create(DbContext dbContext, IEnumerable v }; } +#if EFCORE8 + public IQueryable Create(DbContext dbContext, IEnumerable values) + { + return CreateForSimpleType(dbContext, values); + } + + public IQueryable Create(DbContext dbContext, IEnumerable values) + { + return CreateForSimpleType(dbContext, values); + } +#endif + public IQueryable Create(DbContext dbContext, IEnumerable values, Action>? configure) where TSource : notnull { @@ -412,9 +426,9 @@ public IQueryable Create(DbContext dbContext, IEnumerable(_serializer, new ValuesWrapper(values, values)); + var deferredValues = new DeferredValues(_serializer, new ValuesWrapper(values, values)); - return CreateForComplexType( + return CreateFor( dbContext, deferredValues, configure @@ -472,6 +486,16 @@ public IQueryable Create(DbContext dbContext, IEnumerable)Create(dbContext, stringValues); } +#if EFCORE8 + else if (values is IEnumerable dateOnlyValues) + { + return (IQueryable)Create(dbContext, dateOnlyValues); + } + else if (values is IEnumerable timeOnlyValues) + { + return (IQueryable)Create(dbContext, timeOnlyValues); + } +#endif else { throw new NotImplementedException(typeof(TSource).FullName); diff --git a/src/QueryableValues.SqlServer/SqlServer/XmlQueryableFactory.cs b/src/QueryableValues.SqlServer/SqlServer/XmlQueryableFactory.cs index 2b3f008..e598da2 100644 --- a/src/QueryableValues.SqlServer/SqlServer/XmlQueryableFactory.cs +++ b/src/QueryableValues.SqlServer/SqlServer/XmlQueryableFactory.cs @@ -21,7 +21,7 @@ protected override SqlParameter GetValuesParameter() return new SqlParameter(null, SqlDbType.Xml); } - protected override string GetSqlForComplexTypes(IEntityOptionsBuilder entityOptions, bool useSelectTopOptimization, IReadOnlyList mappings) + protected override string GetSql(IEntityOptionsBuilder entityOptions, bool useSelectTopOptimization, IReadOnlyList mappings) { var sb = StringBuilderPool.Get(); @@ -113,6 +113,14 @@ protected override string GetSqlForComplexTypes(IEntityOptionsBuilder entityOpti sb.Append("xs:string?', 'varchar(max)'"); } break; +#if EFCORE8 + case EntityPropertyTypeName.DateOnly: + sb.Append("xs:date?', 'date'"); + break; + case EntityPropertyTypeName.TimeOnly: + sb.Append("xs:time?', 'time'"); + break; +#endif default: throw new NotImplementedException(mapping.TypeName.ToString()); } @@ -120,7 +128,14 @@ protected override string GetSqlForComplexTypes(IEntityOptionsBuilder entityOpti sb.Append(") [").Append(targetName).Append(']'); } - AppendUnmappedProperties(sb, mappings); + if (typeof(TEntity) == typeof(ComplexQueryableValuesEntity)) + { + // This is necessary because, in some cases, EF will render all the properties of TEntity + // in the outer parts of the query, regardless of the number of properties that were actually projected. + // This behavior was introduced in EF7+. + // See JoinWithProjection test for an example. + AppendUnmappedProperties(sb, mappings); + } sb.AppendLine(); sb.Append("FROM {0}.nodes('/R[1]/V') N(I)").AppendLine(); @@ -133,11 +148,11 @@ protected override string GetSqlForComplexTypes(IEntityOptionsBuilder entityOpti StringBuilderPool.Return(sb); } - static void AppendUnmappedProperties(System.Text.StringBuilder sb, IReadOnlyList< EntityPropertyMapping> mappings) + static void AppendUnmappedProperties(System.Text.StringBuilder sb, IReadOnlyList mappings) { var hasUnmappedProperty = false; - foreach (var unmappedPropertyName in QueryableValuesEntity.GetUnmappedPropertyNames(mappings)) + foreach (var unmappedPropertyName in ComplexQueryableValuesEntity.GetUnmappedPropertyNames(mappings)) { if (hasUnmappedProperty) { diff --git a/src/SharedProjectProperties.xml b/src/SharedProjectProperties.xml index 93b357b..0f5797e 100644 --- a/src/SharedProjectProperties.xml +++ b/src/SharedProjectProperties.xml @@ -18,8 +18,6 @@ - - diff --git a/tests/QueryableValues.SqlServer.Tests/EntityPropertyMappingTests.cs b/tests/QueryableValues.SqlServer.Tests/EntityPropertyMappingTests.cs new file mode 100644 index 0000000..0f23ed1 --- /dev/null +++ b/tests/QueryableValues.SqlServer.Tests/EntityPropertyMappingTests.cs @@ -0,0 +1,26 @@ +ο»Ώusing System; +using Xunit; + +namespace BlazarTech.QueryableValues.SqlServer.Tests +{ + public class EntityPropertyMappingTests + { + class DummyClass + { + public int MyProperty { get; set; } + } + + [Fact] + public void GetMappings_Should_Throw() + { + Assert.Throws(() => EntityPropertyMapping.GetMappings(typeof(DummyClass), typeof(DummyClass))); + } + + [Fact] + public void GetMappings_Should_NotThrow() + { + EntityPropertyMapping.GetMappings(typeof(DummyClass), typeof(SimpleQueryableValuesEntity)); + EntityPropertyMapping.GetMappings(typeof(DummyClass), typeof(ComplexQueryableValuesEntity)); + } + } +} diff --git a/tests/QueryableValues.SqlServer.Tests/Integration/ComplexTypeTests.cs b/tests/QueryableValues.SqlServer.Tests/Integration/ComplexTypeTests.cs index df6f7b0..27fc13d 100644 --- a/tests/QueryableValues.SqlServer.Tests/Integration/ComplexTypeTests.cs +++ b/tests/QueryableValues.SqlServer.Tests/Integration/ComplexTypeTests.cs @@ -51,6 +51,12 @@ class TestType public char? CharUnicodeNullableValue { get; set; } public string? StringValue { get; set; } public string? StringUnicodeValue { get; set; } +#if EFCORE8 + public DateOnly DateOnlyValue { get; set; } + public DateOnly? DateOnlyNullableValue { get; set; } + public TimeOnly TimeOnlyValue { get; set; } + public TimeOnly? TimeOnlyNullableValue { get; set; } +#endif } public struct TestEntityStruct @@ -214,7 +220,13 @@ public async Task MustMatchSequenceOfTestTypeUsesDefaults() GuidNullableValue = Guid.Parse("46367e3b-77cd-4e4e-a931-cf8b69e84cf2"), CharValue = 'A', CharUnicodeValue = '1', - StringValue = "Lorem ipsum dolor sit amet" + StringValue = "Lorem ipsum dolor sit amet", +#if EFCORE8 + DateOnlyValue = DateOnly.MaxValue, + DateOnlyNullableValue = DateOnly.MaxValue, + TimeOnlyValue = TimeOnly.MaxValue, + TimeOnlyNullableValue = TimeOnly.MaxValue, +#endif }, new TestType { @@ -234,7 +246,13 @@ public async Task MustMatchSequenceOfTestTypeUsesDefaults() GuidNullableValue = Guid.Empty, CharValue = ' ', CharUnicodeValue = ' ', - StringValue = "" + StringValue = "", +#if EFCORE8 + DateOnlyValue = DateOnly.MinValue, + DateOnlyNullableValue = DateOnly.MinValue, + TimeOnlyValue = TimeOnly.MinValue, + TimeOnlyNullableValue = TimeOnly.MinValue, +#endif }, new TestType { @@ -284,7 +302,13 @@ public async Task MustMatchSequenceOfTestTypeUsesConfiguration() Int32EnumValue = Int32Enum.A, Int32EnumNullableValue =Int32Enum.B, Int64EnumValue = Int64Enum.A, - Int64EnumNullableValue = Int64Enum.B + Int64EnumNullableValue = Int64Enum.B, +#if EFCORE8 + DateOnlyValue = DateOnly.MaxValue, + DateOnlyNullableValue = DateOnly.MaxValue, + TimeOnlyValue = TimeOnly.MaxValue, + TimeOnlyNullableValue = TimeOnly.MaxValue, +#endif }, new TestType { @@ -310,7 +334,13 @@ public async Task MustMatchSequenceOfTestTypeUsesConfiguration() ByteEnumValue = ByteEnum.None, Int16EnumValue = Int16Enum.A, Int32EnumValue = Int32Enum.B, - Int64EnumValue = Int64Enum.C + Int64EnumValue = Int64Enum.C, +#if EFCORE8 + DateOnlyValue = DateOnly.MinValue, + DateOnlyNullableValue = DateOnly.MinValue, + TimeOnlyValue = TimeOnly.MinValue, + TimeOnlyNullableValue = TimeOnly.MinValue, +#endif }, new TestType { @@ -319,7 +349,7 @@ public async Task MustMatchSequenceOfTestTypeUsesConfiguration() CharUnicodeValue = ' ', ByteEnumNullableValue = ByteEnum.None, Int16EnumNullableValue = Int16Enum.A, - Int32EnumNullableValue =Int32Enum.B, + Int32EnumNullableValue = Int32Enum.B, Int64EnumNullableValue = Int64Enum.C } }; @@ -972,6 +1002,52 @@ orderby td.Id Assert.Equal(expected, actual); } + +#if EFCORE8 + [Fact] + public async Task JoinWithDateOnly() + { + var values = new[] + { + new { Id = 1, Value = DateOnly.MinValue }, + new { Id = 3, Value = DateOnly.MaxValue } + }; + + var expected = new[] { 1, 3 }; + + var query = + from td in _db.TestData + join v in _db.AsQueryableValues(values) on new { td.Id, Value = td.DateOnlyValue } equals new { v.Id, v.Value } + orderby td.Id + select td.Id; + + var actual = await query.ToListAsync(); + + Assert.Equal(expected, actual); + } + + [Fact] + public async Task JoinWithTimeOnly() + { + var values = new[] + { + new { Id = 1, Value = TimeOnly.MinValue }, + new { Id = 3, Value = TimeOnly.MaxValue } + }; + + var expected = new[] { 1, 3 }; + + var query = + from td in _db.TestData + join v in _db.AsQueryableValues(values) on new { td.Id, Value = td.TimeOnlyValue } equals new { v.Id, v.Value } + orderby td.Id + select td.Id; + + var actual = await query.ToListAsync(); + + Assert.Equal(expected, actual); + } +#endif } [Collection("DbContext")] diff --git a/tests/QueryableValues.SqlServer.Tests/Integration/DbContextFixture.cs b/tests/QueryableValues.SqlServer.Tests/Integration/DbContextFixture.cs index 328e444..3bd97fa 100644 --- a/tests/QueryableValues.SqlServer.Tests/Integration/DbContextFixture.cs +++ b/tests/QueryableValues.SqlServer.Tests/Integration/DbContextFixture.cs @@ -53,7 +53,11 @@ private async Task Seed() { new ChildEntity(), new ChildEntity() - } + }, +#if EFCORE8 + DateOnlyValue = DateOnly.MinValue, + TimeOnlyValue = TimeOnly.MinValue, +#endif }, new TestDataEntity { @@ -67,7 +71,11 @@ private async Task Seed() DateTimeValue = dateTimeOffset.DateTime, DateTimeOffsetValue = dateTimeOffset, GuidValue = Guid.Parse("df2c9bfe-9d83-4331-97ce-2876d5dc6576"), - EnumValue = TestEnum.Value1000 + EnumValue = TestEnum.Value1000, +#if EFCORE8 + DateOnlyValue = DateOnly.FromDateTime(dateTimeOffset.DateTime), + TimeOnlyValue = TimeOnly.FromDateTime(dateTimeOffset.DateTime), +#endif }, new TestDataEntity { @@ -90,7 +98,11 @@ private async Task Seed() ChildEntity = new List { new ChildEntity() - } + }, +#if EFCORE8 + DateOnlyValue = DateOnly.MaxValue, + TimeOnlyValue = TimeOnly.MaxValue, +#endif } }; diff --git a/tests/QueryableValues.SqlServer.Tests/Integration/MyDbContextBase.cs b/tests/QueryableValues.SqlServer.Tests/Integration/MyDbContextBase.cs index 52011a1..ae42477 100644 --- a/tests/QueryableValues.SqlServer.Tests/Integration/MyDbContextBase.cs +++ b/tests/QueryableValues.SqlServer.Tests/Integration/MyDbContextBase.cs @@ -135,6 +135,10 @@ public class TestDataEntity public Guid GuidValue { get; set; } public TestEnum EnumValue { get; set; } public ICollection ChildEntity { get; set; } = default!; +#if EFCORE8 + public DateOnly DateOnlyValue { get; set; } + public TimeOnly TimeOnlyValue { get; set; } +#endif } public class ChildEntity diff --git a/tests/QueryableValues.SqlServer.Tests/Integration/SimpleTypeTests.cs b/tests/QueryableValues.SqlServer.Tests/Integration/SimpleTypeTests.cs index feb1d95..145eca6 100644 --- a/tests/QueryableValues.SqlServer.Tests/Integration/SimpleTypeTests.cs +++ b/tests/QueryableValues.SqlServer.Tests/Integration/SimpleTypeTests.cs @@ -837,6 +837,11 @@ public async Task MustBeEmpty() await AssertEmpty(); await AssertEmpty(); +#if EFCORE8 + await AssertEmpty(); + await AssertEmpty(); +#endif + // Coverage check. var expectedTestCount = EntityPropertyMapping.SimpleTypes.Count - 1; Assert.Equal(expectedTestCount, testCounter); @@ -894,6 +899,11 @@ public async Task MustMatchCount() await AssertCount(i => 'A'); await AssertCount(i => $"Test {i}"); +#if EFCORE8 + await AssertCount(i => DateOnly.MinValue.AddDays(i)); + await AssertCount(i => TimeOnly.MinValue.Add(TimeSpan.FromSeconds(i))); +#endif + // Coverage check. var expectedTestCount = EntityPropertyMapping.SimpleTypes.Count - 1; Assert.Equal(expectedTestCount, testCounter); @@ -1005,6 +1015,91 @@ orderby td.Id Assert.Equal(1, actual[0].Id); Assert.Equal(2, actual[0].ChildEntity.Count); } + +#if EFCORE8 + [Fact] + public async Task MustMatchSequenceOfDateOnly() + { + var now = DateTime.Now; + + var values = new[] { + DateOnly.FromDateTime(now), + DateOnly.FromDateTime(now.AddHours(1)), + DateOnly.FromDateTime(now.AddDays(1)), + DateOnly.FromDateTime(now.AddMonths(1)), + DateOnly.FromDateTime(now.AddYears(1)) + }; + + var actual = await _db.AsQueryableValues(values).ToListAsync(); + + Assert.Equal(values, actual); + } + + [Fact] + public async Task MustMatchSequenceOfTimeOnly() + { + var now = DateTime.Now; + + var values = new[] { + TimeOnly.FromDateTime(now), + TimeOnly.FromDateTime(now.AddHours(1)), + TimeOnly.FromDateTime(now.AddMinutes(1)), + TimeOnly.FromDateTime(now.AddSeconds(1)), + TimeOnly.FromDateTime(now.AddMilliseconds(1)), + TimeOnly.FromDateTime(now.AddMicroseconds(1)) + }; + + var actual = await _db.AsQueryableValues(values).ToListAsync(); + + Assert.Equal(values, actual); + } + + [Fact] + public async Task QueryEntityDateOnly() + { + var date = new DateOnly(1999, 12, 31); + + var values = new[] { + DateOnly.MinValue, + date + }; + + var expected = new[] { 1, 2 }; + + var actual = await ( + from i in _db.TestData + join v in _db.AsQueryableValues(values) on i.DateOnlyValue equals v + orderby i.Id + select i.Id + ) + .ToArrayAsync(); + + Assert.Equal(expected, actual); + } + + [Fact] + public async Task QueryEntityTimeOnly() + { + var time = new TimeOnly(23, 59, 59); + + var values = new[] { + TimeOnly.MinValue, + time + }; + + var expected = new[] { 1, 2 }; + + var actual = await ( + from i in _db.TestData + join v in _db.AsQueryableValues(values) on i.TimeOnlyValue equals v + orderby i.Id + select i.Id + ) + .ToArrayAsync(); + + Assert.Equal(expected, actual); + } +#endif } [Collection("DbContext")] diff --git a/tests/QueryableValues.SqlServer.Tests/Serializers/XmlSerializerTests.cs b/tests/QueryableValues.SqlServer.Tests/Serializers/XmlSerializerTests.cs index ce24804..96b0ec1 100644 --- a/tests/QueryableValues.SqlServer.Tests/Serializers/XmlSerializerTests.cs +++ b/tests/QueryableValues.SqlServer.Tests/Serializers/XmlSerializerTests.cs @@ -116,7 +116,7 @@ public void IsValidXmlForComplexType() }; var values = new[] { testType }; - var mappings = EntityPropertyMapping.GetMappings(testType.GetType()); + var mappings = EntityPropertyMapping.GetMappings(testType.GetType(), typeof(ComplexQueryableValuesEntity)); var actual = _serializer.Serialize(values, mappings); var expectedByte = $@"Y=""{byte.MinValue}"" Y1=""{byte.MaxValue}"""; @@ -145,7 +145,7 @@ public void IsValidEmptyXmlForComplexType() }; var values = new[] { testType }; - var mappings = EntityPropertyMapping.GetMappings(testType.GetType()); + var mappings = EntityPropertyMapping.GetMappings(testType.GetType(), typeof(ComplexQueryableValuesEntity)); var xml = _serializer.Serialize(values.Take(0), mappings); Assert.Equal("", xml); }