From 07bab9471556fa17444b9e7d72d143aa242a9e99 Mon Sep 17 00:00:00 2001 From: Ruben Schmidmeister <4602612+bash@users.noreply.github.com> Date: Tue, 24 May 2022 20:24:37 +0200 Subject: [PATCH 1/9] Enable more analyzers --- Directory.Build.props | 5 +++++ .../Extensions/AsyncQueryableExtensions/SingleOrNoneAsync.cs | 3 ++- Funcky.EntityFrameworkCore/Funcky.EntityFrameworkCore.csproj | 4 ++++ Packages.props | 1 + 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 8b2a44d..d5f2adf 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -8,7 +8,12 @@ + + + true + 5.0 + true true diff --git a/Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/SingleOrNoneAsync.cs b/Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/SingleOrNoneAsync.cs index b3bacc5..446e224 100644 --- a/Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/SingleOrNoneAsync.cs +++ b/Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/SingleOrNoneAsync.cs @@ -14,7 +14,8 @@ public static async Task> SingleOrNoneAsync(this IQuery where TSource : notnull => await source .Select(x => Option.Some(x)) - .SingleOrDefaultAsync(); + .SingleOrDefaultAsync() + .ConfigureAwait(false); /// /// Returns the only element of a sequence that satisfies a specified condition as an or a value if no such element exists; this method throws an exception if more than one element satisfies the condition. diff --git a/Funcky.EntityFrameworkCore/Funcky.EntityFrameworkCore.csproj b/Funcky.EntityFrameworkCore/Funcky.EntityFrameworkCore.csproj index 33b9da1..91d785d 100644 --- a/Funcky.EntityFrameworkCore/Funcky.EntityFrameworkCore.csproj +++ b/Funcky.EntityFrameworkCore/Funcky.EntityFrameworkCore.csproj @@ -11,6 +11,10 @@ true snupkg + + true + All + diff --git a/Packages.props b/Packages.props index cdc83c6..0412d5a 100644 --- a/Packages.props +++ b/Packages.props @@ -5,6 +5,7 @@ + From 48ec48df41d38a93e5feb53abe69b64c0fb05c5c Mon Sep 17 00:00:00 2001 From: Ruben Schmidmeister <4602612+bash@users.noreply.github.com> Date: Tue, 24 May 2022 20:25:15 +0200 Subject: [PATCH 2/9] Use newest patch version of EF Core This version fixes issues with .NET 6 --- .github/workflows/build.yml | 2 +- Packages.props | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3ae8091..e7a1bd7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - efcore: ['3.1.23', '5.0.15', '6.0.3'] + efcore: ['3.1.25', '5.0.15', '6.0.3'] env: EntityFrameworkCoreVersion: ${{matrix.efcore}} steps: diff --git a/Packages.props b/Packages.props index 0412d5a..78cc662 100644 --- a/Packages.props +++ b/Packages.props @@ -2,7 +2,7 @@ - + @@ -12,7 +12,7 @@ - + From 1109fb9287b6755fe2034ad09802ada241e1d388 Mon Sep 17 00:00:00 2001 From: Ruben Schmidmeister <4602612+bash@users.noreply.github.com> Date: Tue, 24 May 2022 20:25:56 +0200 Subject: [PATCH 3/9] Accept and propagate cancellation token --- .../AsyncQueryableExtensions/FirstOrNoneAsync.cs | 8 ++++---- .../AsyncQueryableExtensions/LastOrNoneAsync.cs | 8 ++++---- .../AsyncQueryableExtensions/SingleOrNoneAsync.cs | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/FirstOrNoneAsync.cs b/Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/FirstOrNoneAsync.cs index 35dcb74..284d763 100644 --- a/Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/FirstOrNoneAsync.cs +++ b/Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/FirstOrNoneAsync.cs @@ -10,22 +10,22 @@ public static partial class AsyncQueryableExtensions /// Returns the first element of a sequence as an , or a value if the sequence contains no elements. /// /// the inner type of the queryable. - public static async Task> FirstOrNoneAsync(this IQueryable source) + public static async Task> FirstOrNoneAsync(this IQueryable source, CancellationToken cancellationToken = default) where TSource : notnull => await source .Select(x => Option.Some(x)) - .FirstOrDefaultAsync() + .FirstOrDefaultAsync(cancellationToken) .ConfigureAwait(false); /// /// Returns the first element of the sequence as an that satisfies a condition or a value if no such element is found. /// /// the inner type of the queryable. - public static async Task> FirstOrNoneAsync(this IQueryable source, Expression> predicate) + public static async Task> FirstOrNoneAsync(this IQueryable source, Expression> predicate, CancellationToken cancellationToken = default) where TSource : notnull => await source .Where(predicate) .Select(x => Option.Some(x)) - .FirstOrDefaultAsync() + .FirstOrDefaultAsync(cancellationToken) .ConfigureAwait(false); } diff --git a/Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/LastOrNoneAsync.cs b/Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/LastOrNoneAsync.cs index ee1362f..f31ed5f 100644 --- a/Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/LastOrNoneAsync.cs +++ b/Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/LastOrNoneAsync.cs @@ -10,22 +10,22 @@ public static partial class AsyncQueryableExtensions /// Returns the last element of a sequence as an , or a value if the sequence contains no elements. /// /// the inner type of the queryable. - public static async Task> LastOrNoneAsync(this IQueryable source) + public static async Task> LastOrNoneAsync(this IQueryable source, CancellationToken cancellationToken = default) where TSource : notnull => await source .Select(x => Option.Some(x)) - .LastOrDefaultAsync() + .LastOrDefaultAsync(cancellationToken) .ConfigureAwait(false); /// /// Returns the last element of a sequence that satisfies a condition as an or a value if no such element is found. /// /// the inner type of the queryable. - public static async Task> LastOrNoneAsync(this IQueryable source, Expression> predicate) + public static async Task> LastOrNoneAsync(this IQueryable source, Expression> predicate, CancellationToken cancellationToken = default) where TSource : notnull => await source .Where(predicate) .Select(x => Option.Some(x)) - .LastOrDefaultAsync() + .LastOrDefaultAsync(cancellationToken) .ConfigureAwait(false); } diff --git a/Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/SingleOrNoneAsync.cs b/Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/SingleOrNoneAsync.cs index 446e224..51346a4 100644 --- a/Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/SingleOrNoneAsync.cs +++ b/Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/SingleOrNoneAsync.cs @@ -10,22 +10,22 @@ public static partial class AsyncQueryableExtensions /// Returns the only element of a sequence as an , or a value if the sequence is empty; this method throws an exception if there is more than one element in the sequence. /// /// the inner type of the queryable. - public static async Task> SingleOrNoneAsync(this IQueryable source) + public static async Task> SingleOrNoneAsync(this IQueryable source, CancellationToken cancellationToken = default) where TSource : notnull => await source .Select(x => Option.Some(x)) - .SingleOrDefaultAsync() + .SingleOrDefaultAsync(cancellationToken) .ConfigureAwait(false); /// /// Returns the only element of a sequence that satisfies a specified condition as an or a value if no such element exists; this method throws an exception if more than one element satisfies the condition. /// /// the inner type of the queryable. - public static async Task> SingleOrNoneAsync(this IQueryable source, Expression> predicate) + public static async Task> SingleOrNoneAsync(this IQueryable source, Expression> predicate, CancellationToken cancellationToken = default) where TSource : notnull => await source .Where(predicate) .Select(x => Option.Some(x)) - .SingleOrDefaultAsync() + .SingleOrDefaultAsync(cancellationToken) .ConfigureAwait(false); } From 9ef63718bbffefd375898ed3ef6e0e36dffe2593 Mon Sep 17 00:00:00 2001 From: Ruben Schmidmeister <4602612+bash@users.noreply.github.com> Date: Tue, 24 May 2022 20:29:28 +0200 Subject: [PATCH 4/9] Move to Funcky namespace --- .../AsyncQueryableExtensions/FirstOrNoneAsyncTest.cs | 2 +- .../AsyncQueryableExtensions/LastOrNoneAsyncTest.cs | 2 +- .../AsyncQueryableExtensions/SingleOrNoneAsyncTest.cs | 2 +- .../FirstOrNoneAsync.cs | 4 ++-- .../LastOrNoneAsync.cs | 4 ++-- .../SingleOrNoneAsync.cs | 4 ++-- readme.md | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) rename Funcky.EntityFrameworkCore/Extensions/{AsyncQueryableExtensions => EntityFrameworkQueryableExtensions}/FirstOrNoneAsync.cs (93%) rename Funcky.EntityFrameworkCore/Extensions/{AsyncQueryableExtensions => EntityFrameworkQueryableExtensions}/LastOrNoneAsync.cs (93%) rename Funcky.EntityFrameworkCore/Extensions/{AsyncQueryableExtensions => EntityFrameworkQueryableExtensions}/SingleOrNoneAsync.cs (93%) diff --git a/Funcky.EntityFrameworkCore.Test/Extensions/AsyncQueryableExtensions/FirstOrNoneAsyncTest.cs b/Funcky.EntityFrameworkCore.Test/Extensions/AsyncQueryableExtensions/FirstOrNoneAsyncTest.cs index 738dc78..1698ac6 100644 --- a/Funcky.EntityFrameworkCore.Test/Extensions/AsyncQueryableExtensions/FirstOrNoneAsyncTest.cs +++ b/Funcky.EntityFrameworkCore.Test/Extensions/AsyncQueryableExtensions/FirstOrNoneAsyncTest.cs @@ -1,4 +1,4 @@ -using Funcky.EntityFrameworkCore.Extensions; +using Funcky.Extensions; using Funcky.Xunit; using Xunit; diff --git a/Funcky.EntityFrameworkCore.Test/Extensions/AsyncQueryableExtensions/LastOrNoneAsyncTest.cs b/Funcky.EntityFrameworkCore.Test/Extensions/AsyncQueryableExtensions/LastOrNoneAsyncTest.cs index d45950f..3d870b7 100644 --- a/Funcky.EntityFrameworkCore.Test/Extensions/AsyncQueryableExtensions/LastOrNoneAsyncTest.cs +++ b/Funcky.EntityFrameworkCore.Test/Extensions/AsyncQueryableExtensions/LastOrNoneAsyncTest.cs @@ -1,4 +1,4 @@ -using Funcky.EntityFrameworkCore.Extensions; +using Funcky.Extensions; using Funcky.Xunit; using Xunit; diff --git a/Funcky.EntityFrameworkCore.Test/Extensions/AsyncQueryableExtensions/SingleOrNoneAsyncTest.cs b/Funcky.EntityFrameworkCore.Test/Extensions/AsyncQueryableExtensions/SingleOrNoneAsyncTest.cs index 05787a3..7c8b107 100644 --- a/Funcky.EntityFrameworkCore.Test/Extensions/AsyncQueryableExtensions/SingleOrNoneAsyncTest.cs +++ b/Funcky.EntityFrameworkCore.Test/Extensions/AsyncQueryableExtensions/SingleOrNoneAsyncTest.cs @@ -1,4 +1,4 @@ -using Funcky.EntityFrameworkCore.Extensions; +using Funcky.Extensions; using Funcky.Xunit; using Xunit; diff --git a/Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/FirstOrNoneAsync.cs b/Funcky.EntityFrameworkCore/Extensions/EntityFrameworkQueryableExtensions/FirstOrNoneAsync.cs similarity index 93% rename from Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/FirstOrNoneAsync.cs rename to Funcky.EntityFrameworkCore/Extensions/EntityFrameworkQueryableExtensions/FirstOrNoneAsync.cs index 284d763..23f86bc 100644 --- a/Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/FirstOrNoneAsync.cs +++ b/Funcky.EntityFrameworkCore/Extensions/EntityFrameworkQueryableExtensions/FirstOrNoneAsync.cs @@ -2,9 +2,9 @@ using Funcky.Monads; using Microsoft.EntityFrameworkCore; -namespace Funcky.EntityFrameworkCore.Extensions; +namespace Funcky.Extensions; -public static partial class AsyncQueryableExtensions +public static partial class EntityFrameworkQueryableExtensions { /// /// Returns the first element of a sequence as an , or a value if the sequence contains no elements. diff --git a/Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/LastOrNoneAsync.cs b/Funcky.EntityFrameworkCore/Extensions/EntityFrameworkQueryableExtensions/LastOrNoneAsync.cs similarity index 93% rename from Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/LastOrNoneAsync.cs rename to Funcky.EntityFrameworkCore/Extensions/EntityFrameworkQueryableExtensions/LastOrNoneAsync.cs index f31ed5f..f5c6411 100644 --- a/Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/LastOrNoneAsync.cs +++ b/Funcky.EntityFrameworkCore/Extensions/EntityFrameworkQueryableExtensions/LastOrNoneAsync.cs @@ -2,9 +2,9 @@ using Funcky.Monads; using Microsoft.EntityFrameworkCore; -namespace Funcky.EntityFrameworkCore.Extensions; +namespace Funcky.Extensions; -public static partial class AsyncQueryableExtensions +public static partial class EntityFrameworkQueryableExtensions { /// /// Returns the last element of a sequence as an , or a value if the sequence contains no elements. diff --git a/Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/SingleOrNoneAsync.cs b/Funcky.EntityFrameworkCore/Extensions/EntityFrameworkQueryableExtensions/SingleOrNoneAsync.cs similarity index 93% rename from Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/SingleOrNoneAsync.cs rename to Funcky.EntityFrameworkCore/Extensions/EntityFrameworkQueryableExtensions/SingleOrNoneAsync.cs index 51346a4..966f248 100644 --- a/Funcky.EntityFrameworkCore/Extensions/AsyncQueryableExtensions/SingleOrNoneAsync.cs +++ b/Funcky.EntityFrameworkCore/Extensions/EntityFrameworkQueryableExtensions/SingleOrNoneAsync.cs @@ -2,9 +2,9 @@ using Funcky.Monads; using Microsoft.EntityFrameworkCore; -namespace Funcky.EntityFrameworkCore.Extensions; +namespace Funcky.Extensions; -public static partial class AsyncQueryableExtensions +public static partial class EntityFrameworkQueryableExtensions { /// /// Returns the only element of a sequence as an , or a value if the sequence is empty; this method throws an exception if there is more than one element in the sequence. diff --git a/readme.md b/readme.md index 8cdbb86..5b9e6fa 100644 --- a/readme.md +++ b/readme.md @@ -14,7 +14,7 @@ These are analogous to the ones provided by [`EntityFrameworkQueryableExtensions Example: ```csharp using System; -using Funcky.EntityFrameworkCore.Extensions; +using Funcky.Extensions; using Microsoft.EntityFrameworkCore; DbContext context; From 6a7faeb09ecdd7e84b61200e478bc9a03730f112 Mon Sep 17 00:00:00 2001 From: Ruben Schmidmeister <4602612+bash@users.noreply.github.com> Date: Tue, 24 May 2022 20:36:12 +0200 Subject: [PATCH 5/9] Label property groups --- Funcky.EntityFrameworkCore/Funcky.EntityFrameworkCore.csproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Funcky.EntityFrameworkCore/Funcky.EntityFrameworkCore.csproj b/Funcky.EntityFrameworkCore/Funcky.EntityFrameworkCore.csproj index 91d785d..1ad8501 100644 --- a/Funcky.EntityFrameworkCore/Funcky.EntityFrameworkCore.csproj +++ b/Funcky.EntityFrameworkCore/Funcky.EntityFrameworkCore.csproj @@ -8,10 +8,12 @@ Interoperability between Funcky and EF Core Functional Monad EFCore EntityFramework 0.1.0 + + true snupkg - + true All From d4e9ae5025e0b0069152de92c44c32235b02273a Mon Sep 17 00:00:00 2001 From: Ruben Schmidmeister <4602612+bash@users.noreply.github.com> Date: Tue, 24 May 2022 20:41:56 +0200 Subject: [PATCH 6/9] Define EOL handling via .gitattributes --- .gitattributes | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitattributes b/.gitattributes index 9cc4965..ffba596 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,3 @@ +* text=auto eol=lf +*.sln text eol=crlf *.cs diff=csharp From 929b28c01d10819d80167d93c8b8fc90a2fb77bd Mon Sep 17 00:00:00 2001 From: Ruben Schmidmeister <4602612+bash@users.noreply.github.com> Date: Tue, 24 May 2022 20:47:03 +0200 Subject: [PATCH 7/9] Add public API analyzer --- .../Funcky.EntityFrameworkCore.csproj | 2 ++ Funcky.EntityFrameworkCore/PublicAPI.Shipped.txt | 1 + Funcky.EntityFrameworkCore/PublicAPI.Unshipped.txt | 8 ++++++++ Packages.props | 1 + 4 files changed, 12 insertions(+) create mode 100644 Funcky.EntityFrameworkCore/PublicAPI.Shipped.txt create mode 100644 Funcky.EntityFrameworkCore/PublicAPI.Unshipped.txt diff --git a/Funcky.EntityFrameworkCore/Funcky.EntityFrameworkCore.csproj b/Funcky.EntityFrameworkCore/Funcky.EntityFrameworkCore.csproj index 1ad8501..1fe81bc 100644 --- a/Funcky.EntityFrameworkCore/Funcky.EntityFrameworkCore.csproj +++ b/Funcky.EntityFrameworkCore/Funcky.EntityFrameworkCore.csproj @@ -12,6 +12,7 @@ true snupkg + $(NoWarn);RS0026 true @@ -20,5 +21,6 @@ + diff --git a/Funcky.EntityFrameworkCore/PublicAPI.Shipped.txt b/Funcky.EntityFrameworkCore/PublicAPI.Shipped.txt new file mode 100644 index 0000000..ab058de --- /dev/null +++ b/Funcky.EntityFrameworkCore/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/Funcky.EntityFrameworkCore/PublicAPI.Unshipped.txt b/Funcky.EntityFrameworkCore/PublicAPI.Unshipped.txt new file mode 100644 index 0000000..25760c0 --- /dev/null +++ b/Funcky.EntityFrameworkCore/PublicAPI.Unshipped.txt @@ -0,0 +1,8 @@ +#nullable enable +Funcky.Extensions.EntityFrameworkQueryableExtensions +static Funcky.Extensions.EntityFrameworkQueryableExtensions.FirstOrNoneAsync(this System.Linq.IQueryable! source, System.Linq.Expressions.Expression!>! predicate, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task>! +static Funcky.Extensions.EntityFrameworkQueryableExtensions.FirstOrNoneAsync(this System.Linq.IQueryable! source, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task>! +static Funcky.Extensions.EntityFrameworkQueryableExtensions.LastOrNoneAsync(this System.Linq.IQueryable! source, System.Linq.Expressions.Expression!>! predicate, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task>! +static Funcky.Extensions.EntityFrameworkQueryableExtensions.LastOrNoneAsync(this System.Linq.IQueryable! source, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task>! +static Funcky.Extensions.EntityFrameworkQueryableExtensions.SingleOrNoneAsync(this System.Linq.IQueryable! source, System.Linq.Expressions.Expression!>! predicate, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task>! +static Funcky.Extensions.EntityFrameworkQueryableExtensions.SingleOrNoneAsync(this System.Linq.IQueryable! source, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task>! diff --git a/Packages.props b/Packages.props index 78cc662..81e01af 100644 --- a/Packages.props +++ b/Packages.props @@ -7,6 +7,7 @@ + From e809bb80fb6f62c27286805194d2c450012c8f4d Mon Sep 17 00:00:00 2001 From: Ruben Schmidmeister <4602612+bash@users.noreply.github.com> Date: Tue, 24 May 2022 20:51:48 +0200 Subject: [PATCH 8/9] Update changelog --- changelog.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/changelog.md b/changelog.md index e63978d..b9e16ae 100644 --- a/changelog.md +++ b/changelog.md @@ -1,4 +1,7 @@ # Changelog +## Unreleased +* Breaking: Add an optional `cancellationToken` parameter to all async `IQueryable` extensions. (polyadic/funcky#433) +* Breaking: Move extensions to `Funcky.Extensions` namespace. (polyadic/funcky#460) ## 0.1.0 Initial release From 7ced66530b04a615383562ac3c4fcbf51423d53a Mon Sep 17 00:00:00 2001 From: Ruben Schmidmeister <4602612+bash@users.noreply.github.com> Date: Tue, 24 May 2022 20:53:40 +0200 Subject: [PATCH 9/9] Add readme file to NuGet package --- Funcky.EntityFrameworkCore/Funcky.EntityFrameworkCore.csproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Funcky.EntityFrameworkCore/Funcky.EntityFrameworkCore.csproj b/Funcky.EntityFrameworkCore/Funcky.EntityFrameworkCore.csproj index 1fe81bc..05a7e7c 100644 --- a/Funcky.EntityFrameworkCore/Funcky.EntityFrameworkCore.csproj +++ b/Funcky.EntityFrameworkCore/Funcky.EntityFrameworkCore.csproj @@ -8,6 +8,7 @@ Interoperability between Funcky and EF Core Functional Monad EFCore EntityFramework 0.1.0 + readme.md true @@ -23,4 +24,7 @@ + + +