async handler with better cohabitaton logic.
This commit is contained in:
		
							parent
							
								
									50f3bfee93
								
							
						
					
					
						commit
						828f868fe4
					
				
							
								
								
									
										12
									
								
								Data.sln
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								Data.sln
									
									
									
									
									
								
							| @ -15,6 +15,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution | |||||||
| EndProject | EndProject | ||||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PoweredSoft.Data.EntityFrameworkCore.Test", "PoweredSoft.Data.EntityFrameworkCore.Test\PoweredSoft.Data.EntityFrameworkCore.Test.csproj", "{1F0B95F6-2E97-4FC2-A452-F8A071CBEF4B}" | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PoweredSoft.Data.EntityFrameworkCore.Test", "PoweredSoft.Data.EntityFrameworkCore.Test\PoweredSoft.Data.EntityFrameworkCore.Test.csproj", "{1F0B95F6-2E97-4FC2-A452-F8A071CBEF4B}" | ||||||
| EndProject | EndProject | ||||||
|  | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PoweredSoft.Data", "PoweredSoft.Data\PoweredSoft.Data.csproj", "{62DDEA81-6B09-4116-A91B-81FE66AB477B}" | ||||||
|  | EndProject | ||||||
|  | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PoweredSoft.Data.MongoDB", "PoweredSoft.Data.MongoDB\PoweredSoft.Data.MongoDB.csproj", "{34BED188-2B88-4CAD-8DD0-6FC70D156902}" | ||||||
|  | EndProject | ||||||
| Global | Global | ||||||
| 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||||
| 		Debug|Any CPU = Debug|Any CPU | 		Debug|Any CPU = Debug|Any CPU | ||||||
| @ -33,6 +37,14 @@ Global | |||||||
| 		{1F0B95F6-2E97-4FC2-A452-F8A071CBEF4B}.Debug|Any CPU.Build.0 = Debug|Any CPU | 		{1F0B95F6-2E97-4FC2-A452-F8A071CBEF4B}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||||
| 		{1F0B95F6-2E97-4FC2-A452-F8A071CBEF4B}.Release|Any CPU.ActiveCfg = Release|Any CPU | 		{1F0B95F6-2E97-4FC2-A452-F8A071CBEF4B}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||||
| 		{1F0B95F6-2E97-4FC2-A452-F8A071CBEF4B}.Release|Any CPU.Build.0 = Release|Any CPU | 		{1F0B95F6-2E97-4FC2-A452-F8A071CBEF4B}.Release|Any CPU.Build.0 = Release|Any CPU | ||||||
|  | 		{62DDEA81-6B09-4116-A91B-81FE66AB477B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{62DDEA81-6B09-4116-A91B-81FE66AB477B}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||||
|  | 		{62DDEA81-6B09-4116-A91B-81FE66AB477B}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||||
|  | 		{62DDEA81-6B09-4116-A91B-81FE66AB477B}.Release|Any CPU.Build.0 = Release|Any CPU | ||||||
|  | 		{34BED188-2B88-4CAD-8DD0-6FC70D156902}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{34BED188-2B88-4CAD-8DD0-6FC70D156902}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||||
|  | 		{34BED188-2B88-4CAD-8DD0-6FC70D156902}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||||
|  | 		{34BED188-2B88-4CAD-8DD0-6FC70D156902}.Release|Any CPU.Build.0 = Release|Any CPU | ||||||
| 	EndGlobalSection | 	EndGlobalSection | ||||||
| 	GlobalSection(SolutionProperties) = preSolution | 	GlobalSection(SolutionProperties) = preSolution | ||||||
| 		HideSolutionNode = FALSE | 		HideSolutionNode = FALSE | ||||||
|  | |||||||
| @ -7,12 +7,15 @@ using System.Threading.Tasks; | |||||||
| 
 | 
 | ||||||
| namespace PoweredSoft.Data.Core | namespace PoweredSoft.Data.Core | ||||||
| { | { | ||||||
|     public interface IAsyncQueryableFactory |     public interface IAsyncQueryableHandlerService | ||||||
|     { |     { | ||||||
|         Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)); |         Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)); | ||||||
|         Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken)); |         Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken)); | ||||||
|         Task<List<T>> ToListAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)); |         Task<List<T>> ToListAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)); | ||||||
|         Task<int> CountAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)); |         Task<int> CountAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)); | ||||||
|         Task<long> LongCountAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)); |         Task<long> LongCountAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)); | ||||||
|  |         Task<bool> AnyAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken)); | ||||||
|  |         Task<bool> AnyAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)); | ||||||
|  |         bool CanHandle<T>(IQueryable<T> queryable); | ||||||
|     } |     } | ||||||
| } | } | ||||||
							
								
								
									
										22
									
								
								PoweredSoft.Data.Core/IAsyncQueryableService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								PoweredSoft.Data.Core/IAsyncQueryableService.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | |||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Linq.Expressions; | ||||||
|  | using System.Threading; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  | 
 | ||||||
|  | namespace PoweredSoft.Data.Core | ||||||
|  | { | ||||||
|  |     public interface IAsyncQueryableService | ||||||
|  |     { | ||||||
|  |         IAsyncQueryableHandlerService GetAsyncQueryableHandler<T>(IQueryable<T> queryable); | ||||||
|  | 
 | ||||||
|  |         Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)); | ||||||
|  |         Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken)); | ||||||
|  |         Task<List<T>> ToListAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)); | ||||||
|  |         Task<int> CountAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)); | ||||||
|  |         Task<long> LongCountAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)); | ||||||
|  |         Task<bool> AnyAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken)); | ||||||
|  |         Task<bool> AnyAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -9,17 +9,15 @@ | |||||||
|     <RepositoryUrl>https://github.com/PoweredSoft/Data</RepositoryUrl> |     <RepositoryUrl>https://github.com/PoweredSoft/Data</RepositoryUrl> | ||||||
|     <RepositoryType>github</RepositoryType> |     <RepositoryType>github</RepositoryType> | ||||||
|     <PackageTags>powered,soft,orm,db,context,ef,ef6,efcore,factory</PackageTags> |     <PackageTags>powered,soft,orm,db,context,ef,ef6,efcore,factory</PackageTags> | ||||||
|     <Version>1.0.2</Version> |     <Version>1.1.0</Version> | ||||||
|     <PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl> |     <PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl> | ||||||
|     <Product>PoweredSoft.Data.Core</Product> |     <Product>PoweredSoft.Data.Core</Product> | ||||||
|     <Description>Library to abstract orm.</Description> |     <Description>Library to abstract orm.</Description> | ||||||
|     <PackageId>PoweredSoft.Data.Core</PackageId> |     <PackageId>PoweredSoft.Data.Core</PackageId> | ||||||
|     <PackageReleaseNotes>Added some methods to the factory to discovery primary keys of the TEntity.</PackageReleaseNotes> |     <PackageReleaseNotes>N/a</PackageReleaseNotes> | ||||||
|     <PackageRequireLicenseAcceptance>False</PackageRequireLicenseAcceptance> |     <PackageRequireLicenseAcceptance>False</PackageRequireLicenseAcceptance> | ||||||
|     <Company>PoweredSoft.Data.Core</Company> |     <Company>PoweredSoft</Company> | ||||||
|     <Authors>PoweredSoft.Data.Core</Authors> |     <Authors>David Lebee</Authors> | ||||||
|     <AssemblyVersion>1.0.2.0</AssemblyVersion> |  | ||||||
|     <FileVersion>1.0.2.0</FileVersion> |  | ||||||
|   </PropertyGroup> |   </PropertyGroup> | ||||||
| 
 | 
 | ||||||
| </Project> | </Project> | ||||||
|  | |||||||
| @ -0,0 +1,40 @@ | |||||||
|  | using PoweredSoft.Test.Mock; | ||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Text; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  | using Xunit; | ||||||
|  | 
 | ||||||
|  | namespace PoweredSoft.Data.EntityFrameworkCore.Test | ||||||
|  | { | ||||||
|  |     public class AsyncQueryableServiceTests | ||||||
|  |     { | ||||||
|  |         [Fact] | ||||||
|  |         public void TestCanHandle() | ||||||
|  |         { | ||||||
|  |             MockContextFactory.SeedAndTestContextFor("AsyncQueryableServiceTests_TestCanHandle", TestSeeders.SimpleSeedScenario, ctx => | ||||||
|  |             { | ||||||
|  |                 var test = new AsyncQueryableHandlerService(); | ||||||
|  |                 IQueryable<Order> query = ctx.Orders; | ||||||
|  |                 var query2 = query.GroupBy(t => t.Customer); | ||||||
|  |                 var query3 = query.Where(t => t.Customer.LastName == "David"); | ||||||
|  | 
 | ||||||
|  |                 Assert.True(test.CanHandle(query)); | ||||||
|  |                 Assert.True(test.CanHandle(query2)); | ||||||
|  |                 Assert.True(test.CanHandle(query3)); | ||||||
|  |             });         | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         [Fact] | ||||||
|  |         public void TestFirstOrDefault() | ||||||
|  |         { | ||||||
|  |             MockContextFactory.SeedAndTestContextFor("AsyncQueryableServiceTests_TestCanHandle", TestSeeders.SimpleSeedScenario, async ctx => | ||||||
|  |             { | ||||||
|  |                 var handler = new AsyncQueryableHandlerService(); | ||||||
|  |                 var service = new AsyncQueryableService(new[] { handler }); | ||||||
|  |                 var first = await service.FirstOrDefaultAsync(ctx.Orders); | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										39
									
								
								PoweredSoft.Data.EntityFrameworkCore.Test/CohabitTest.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								PoweredSoft.Data.EntityFrameworkCore.Test/CohabitTest.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | |||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Text; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  | using Xunit; | ||||||
|  | using MongoDB.Driver; | ||||||
|  | using PoweredSoft.Test.Mock; | ||||||
|  | using PoweredSoft.Data.Core; | ||||||
|  | using System.Linq; | ||||||
|  | using Microsoft.EntityFrameworkCore; | ||||||
|  | 
 | ||||||
|  | namespace PoweredSoft.Data.EntityFrameworkCore.Test | ||||||
|  | { | ||||||
|  |     public class CohabitTest | ||||||
|  |     { | ||||||
|  |         [Fact] | ||||||
|  |         public void TestCohabitation() | ||||||
|  |         { | ||||||
|  |             var mongoHandler = new PoweredSoft.Data.MongoDB.AsyncQueryableHandlerService(); | ||||||
|  |             var efCoreHandler = new PoweredSoft.Data.EntityFrameworkCore.AsyncQueryableHandlerService(); | ||||||
|  |             var service = new PoweredSoft.Data.AsyncQueryableService(new IAsyncQueryableHandlerService[] { mongoHandler, efCoreHandler }); | ||||||
|  | 
 | ||||||
|  |             var mongoClient = new MongoClient(); | ||||||
|  |             var db = mongoClient.GetDatabase("acme"); | ||||||
|  |             var mongoOrders = db.GetCollection<Order>("orders").AsQueryable(); | ||||||
|  | 
 | ||||||
|  |             var options = new DbContextOptionsBuilder<MockContext>().UseInMemoryDatabase(databaseName: "CohabitTest_TestCohabitation").Options; | ||||||
|  |             var context = new MockContext(options); | ||||||
|  |             var set = context.Set<Order>(); | ||||||
|  |             var efCoreOrders = set.AsQueryable(); | ||||||
|  | 
 | ||||||
|  |             var shouldBeMongoHandler = service.GetAsyncQueryableHandler(mongoOrders); | ||||||
|  |             Assert.Equal(mongoHandler, shouldBeMongoHandler); | ||||||
|  | 
 | ||||||
|  |             var shouldBeEfCoreHandler = service.GetAsyncQueryableHandler(efCoreOrders); | ||||||
|  |             Assert.Equal(efCoreHandler, shouldBeEfCoreHandler); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,7 +1,7 @@ | |||||||
| <Project Sdk="Microsoft.NET.Sdk"> | <Project Sdk="Microsoft.NET.Sdk"> | ||||||
| 
 | 
 | ||||||
|   <PropertyGroup> |   <PropertyGroup> | ||||||
|     <TargetFramework>netcoreapp2.1</TargetFramework> |     <TargetFramework>netcoreapp2.2</TargetFramework> | ||||||
| 
 | 
 | ||||||
|     <IsPackable>false</IsPackable> |     <IsPackable>false</IsPackable> | ||||||
|   </PropertyGroup> |   </PropertyGroup> | ||||||
| @ -10,12 +10,14 @@ | |||||||
|     <PackageReference Include="Bogus" Version="24.3.1" /> |     <PackageReference Include="Bogus" Version="24.3.1" /> | ||||||
|     <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="2.1.4" /> |     <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="2.1.4" /> | ||||||
|     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" /> |     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" /> | ||||||
|  |     <PackageReference Include="MongoDB.Driver" Version="2.7.3" /> | ||||||
|     <PackageReference Include="xunit" Version="2.3.1" /> |     <PackageReference Include="xunit" Version="2.3.1" /> | ||||||
|     <PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" /> |     <PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
| 
 | 
 | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ProjectReference Include="..\PoweredSoft.Data.EntityFrameworkCore\PoweredSoft.Data.EntityFrameworkCore.csproj" /> |     <ProjectReference Include="..\PoweredSoft.Data.EntityFrameworkCore\PoweredSoft.Data.EntityFrameworkCore.csproj" /> | ||||||
|  |     <ProjectReference Include="..\PoweredSoft.Data.MongoDB\PoweredSoft.Data.MongoDB.csproj" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
| 
 | 
 | ||||||
| </Project> | </Project> | ||||||
|  | |||||||
| @ -1,4 +1,5 @@ | |||||||
| using Microsoft.EntityFrameworkCore; | using Microsoft.EntityFrameworkCore; | ||||||
|  | using Microsoft.EntityFrameworkCore.Query.Internal; | ||||||
| using PoweredSoft.Data.Core; | using PoweredSoft.Data.Core; | ||||||
| using System; | using System; | ||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
| @ -9,7 +10,7 @@ using System.Threading.Tasks; | |||||||
| 
 | 
 | ||||||
| namespace PoweredSoft.Data.EntityFrameworkCore | namespace PoweredSoft.Data.EntityFrameworkCore | ||||||
| { | { | ||||||
|     public class AsyncQueryableFactory : IAsyncQueryableFactory |     public class AsyncQueryableHandlerService : IAsyncQueryableHandlerService | ||||||
|     { |     { | ||||||
|         public Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)) |         public Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)) | ||||||
|             => queryable.FirstOrDefaultAsync(cancellationToken); |             => queryable.FirstOrDefaultAsync(cancellationToken); | ||||||
| @ -21,5 +22,13 @@ namespace PoweredSoft.Data.EntityFrameworkCore | |||||||
|             => queryable.CountAsync(); |             => queryable.CountAsync(); | ||||||
|         public Task<long> LongCountAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)) |         public Task<long> LongCountAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)) | ||||||
|             => queryable.LongCountAsync(); |             => queryable.LongCountAsync(); | ||||||
|  | 
 | ||||||
|  |         public bool CanHandle<T>(IQueryable<T> queryable) => queryable.Provider is IAsyncQueryProvider; | ||||||
|  | 
 | ||||||
|  |         public Task<bool> AnyAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken)) | ||||||
|  |             => queryable.AnyAsync(predicate, cancellationToken); | ||||||
|  | 
 | ||||||
|  |         public Task<bool> AnyAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)) | ||||||
|  |             => queryable.AnyAsync(cancellationToken); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -13,7 +13,6 @@ namespace PoweredSoft.Data.EntityFrameworkCore | |||||||
|     public class DbContextFactory : IDbContextFactory |     public class DbContextFactory : IDbContextFactory | ||||||
|     { |     { | ||||||
|         private readonly DbContext _context; |         private readonly DbContext _context; | ||||||
|         private MethodInfo _setGenericMethod = null; |  | ||||||
| 
 | 
 | ||||||
|         public DbContextFactory(DbContext dbContext) |         public DbContextFactory(DbContext dbContext) | ||||||
|         { |         { | ||||||
|  | |||||||
| @ -9,17 +9,15 @@ | |||||||
|     <RepositoryUrl>https://github.com/PoweredSoft/Data</RepositoryUrl> |     <RepositoryUrl>https://github.com/PoweredSoft/Data</RepositoryUrl> | ||||||
|     <RepositoryType>github</RepositoryType> |     <RepositoryType>github</RepositoryType> | ||||||
|     <PackageTags>powered,soft,orm,db,context,ef,ef6,efcore,factory</PackageTags> |     <PackageTags>powered,soft,orm,db,context,ef,ef6,efcore,factory</PackageTags> | ||||||
|     <Version>1.0.2</Version> |     <Version>1.1.0</Version> | ||||||
|     <PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl> |     <PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl> | ||||||
|     <Product>PoweredSoft.Data.EntityFrameworkCore</Product> |     <Product>PoweredSoft.Data.EntityFrameworkCore</Product> | ||||||
|     <Description>the abstraction implementation for EF Core.</Description> |     <Description>the abstraction implementation for EF Core.</Description> | ||||||
|     <PackageId>PoweredSoft.Data.EntityFrameworkCore</PackageId> |     <PackageId>PoweredSoft.Data.EntityFrameworkCore</PackageId> | ||||||
|     <PackageReleaseNotes>added support of resolve primary keys.</PackageReleaseNotes> |     <PackageReleaseNotes>N/A</PackageReleaseNotes> | ||||||
|     <PackageRequireLicenseAcceptance>False</PackageRequireLicenseAcceptance> |     <PackageRequireLicenseAcceptance>False</PackageRequireLicenseAcceptance> | ||||||
|     <Company>PoweredSoft.Data.EntityFrameworkCore</Company> |     <Company>PoweredSoft</Company> | ||||||
|     <Authors>PoweredSoft.Data.EntityFrameworkCore</Authors> |     <Authors>David Lebee</Authors> | ||||||
|     <AssemblyVersion>1.0.2.0</AssemblyVersion> |  | ||||||
|     <FileVersion>1.0.2.0</FileVersion> |  | ||||||
|   </PropertyGroup> |   </PropertyGroup> | ||||||
| 
 | 
 | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
| @ -28,6 +26,7 @@ | |||||||
| 
 | 
 | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ProjectReference Include="..\PoweredSoft.Data.Core\PoweredSoft.Data.Core.csproj" /> |     <ProjectReference Include="..\PoweredSoft.Data.Core\PoweredSoft.Data.Core.csproj" /> | ||||||
|  |     <ProjectReference Include="..\PoweredSoft.Data\PoweredSoft.Data.csproj" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
| 
 | 
 | ||||||
| </Project> | </Project> | ||||||
|  | |||||||
| @ -9,10 +9,11 @@ namespace PoweredSoft.Data.EntityFrameworkCore | |||||||
| { | { | ||||||
|     public static class ServiceCollectionExtensions |     public static class ServiceCollectionExtensions | ||||||
|     { |     { | ||||||
|         public static IServiceCollection AddPoweredSoftDataServices(this IServiceCollection services) |         public static IServiceCollection AddPoweredSoftEntityFrameworkCoreDataServices(this IServiceCollection services) | ||||||
|         { |         { | ||||||
|  |             services.AddPoweredSoftDataServices(); | ||||||
|             services.TryAddTransient<IDbContextFactoryProvider, DbContextFactoryProvider>(); |             services.TryAddTransient<IDbContextFactoryProvider, DbContextFactoryProvider>(); | ||||||
|             services.TryAddTransient<IAsyncQueryableFactory, AsyncQueryableFactory>(); |             services.TryAddTransient<IAsyncQueryableHandlerService, AsyncQueryableHandlerService>(); | ||||||
|             return services; |             return services; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
							
								
								
									
										35
									
								
								PoweredSoft.Data.MongoDB/AsyncQueryableHandlerService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								PoweredSoft.Data.MongoDB/AsyncQueryableHandlerService.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | |||||||
|  | using MongoDB.Driver.Linq; | ||||||
|  | using MongoDB.Driver; | ||||||
|  | using PoweredSoft.Data.Core; | ||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Linq.Expressions; | ||||||
|  | using System.Text; | ||||||
|  | using System.Threading; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  | 
 | ||||||
|  | namespace PoweredSoft.Data.MongoDB | ||||||
|  | { | ||||||
|  |     public class AsyncQueryableHandlerService : IAsyncQueryableHandlerService | ||||||
|  |     { | ||||||
|  |         public Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)) | ||||||
|  |             => ((IMongoQueryable<T>)queryable).FirstOrDefaultAsync(cancellationToken); | ||||||
|  |         public Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken)) | ||||||
|  |             => ((IMongoQueryable<T>)queryable).FirstOrDefaultAsync(predicate, cancellationToken); | ||||||
|  |         public Task<List<T>> ToListAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)) | ||||||
|  |             => ((IMongoQueryable<T>)queryable).ToListAsync(cancellationToken); | ||||||
|  |         public Task<int> CountAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)) | ||||||
|  |             => ((IMongoQueryable<T>)queryable).CountAsync(); | ||||||
|  |         public Task<long> LongCountAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)) | ||||||
|  |             => ((IMongoQueryable<T>)queryable).LongCountAsync(); | ||||||
|  | 
 | ||||||
|  |         public bool CanHandle<T>(IQueryable<T> queryable) => queryable is IMongoQueryable<T>; | ||||||
|  | 
 | ||||||
|  |         public Task<bool> AnyAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken)) | ||||||
|  |             => ((IMongoQueryable<T>)queryable).AnyAsync(predicate, cancellationToken); | ||||||
|  | 
 | ||||||
|  |         public Task<bool> AnyAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)) | ||||||
|  |             => ((IMongoQueryable<T>)queryable).AnyAsync(cancellationToken); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										17
									
								
								PoweredSoft.Data.MongoDB/PoweredSoft.Data.MongoDB.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								PoweredSoft.Data.MongoDB/PoweredSoft.Data.MongoDB.csproj
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | |||||||
|  | <Project Sdk="Microsoft.NET.Sdk"> | ||||||
|  | 
 | ||||||
|  |   <PropertyGroup> | ||||||
|  |     <TargetFramework>netstandard2.0</TargetFramework> | ||||||
|  |   </PropertyGroup> | ||||||
|  | 
 | ||||||
|  |   <ItemGroup> | ||||||
|  |     <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" /> | ||||||
|  |     <PackageReference Include="MongoDB.Driver" Version="2.7.3" /> | ||||||
|  |   </ItemGroup> | ||||||
|  | 
 | ||||||
|  |   <ItemGroup> | ||||||
|  |     <ProjectReference Include="..\PoweredSoft.Data.Core\PoweredSoft.Data.Core.csproj" /> | ||||||
|  |     <ProjectReference Include="..\PoweredSoft.Data\PoweredSoft.Data.csproj" /> | ||||||
|  |   </ItemGroup> | ||||||
|  | 
 | ||||||
|  | </Project> | ||||||
							
								
								
									
										19
									
								
								PoweredSoft.Data.MongoDB/ServiceCollectionExtensions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								PoweredSoft.Data.MongoDB/ServiceCollectionExtensions.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | |||||||
|  | using Microsoft.Extensions.DependencyInjection; | ||||||
|  | using Microsoft.Extensions.DependencyInjection.Extensions; | ||||||
|  | using PoweredSoft.Data.Core; | ||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Text; | ||||||
|  | 
 | ||||||
|  | namespace PoweredSoft.Data.MongoDB | ||||||
|  | { | ||||||
|  |     public static class ServiceCollectionExtensions | ||||||
|  |     { | ||||||
|  |         public static IServiceCollection AddPoweredSoftMongoDBDataServices(this IServiceCollection services) | ||||||
|  |         { | ||||||
|  |             services.AddPoweredSoftDataServices(); | ||||||
|  |             services.TryAddTransient<IAsyncQueryableHandlerService, AsyncQueryableHandlerService>(); | ||||||
|  |             return services; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										56
									
								
								PoweredSoft.Data/AsyncQueryableService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								PoweredSoft.Data/AsyncQueryableService.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,56 @@ | |||||||
|  | using PoweredSoft.Data.Core; | ||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Linq.Expressions; | ||||||
|  | using System.Threading; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  | 
 | ||||||
|  | namespace PoweredSoft.Data | ||||||
|  | { | ||||||
|  |     public class AsyncQueryableService : IAsyncQueryableService | ||||||
|  |     { | ||||||
|  |         public AsyncQueryableService(IEnumerable<IAsyncQueryableHandlerService> asyncQueryableFactories) | ||||||
|  |         { | ||||||
|  |             AsyncQueryableFactories = asyncQueryableFactories; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public IEnumerable<IAsyncQueryableHandlerService> AsyncQueryableFactories { get; } | ||||||
|  | 
 | ||||||
|  |         public Task<int> CountAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)) | ||||||
|  |             => GetAsyncQueryableHandlerOrThrow(queryable).CountAsync(queryable, cancellationToken); | ||||||
|  | 
 | ||||||
|  |         public Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)) | ||||||
|  |             => GetAsyncQueryableHandlerOrThrow(queryable).FirstOrDefaultAsync(queryable, cancellationToken); | ||||||
|  | 
 | ||||||
|  |         public Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken)) | ||||||
|  |             => GetAsyncQueryableHandlerOrThrow(queryable).FirstOrDefaultAsync(queryable, predicate, cancellationToken); | ||||||
|  | 
 | ||||||
|  |         private IAsyncQueryableHandlerService GetAsyncQueryableHandlerOrThrow<T>(IQueryable<T> queryable) | ||||||
|  |         { | ||||||
|  |             var handler = this.GetAsyncQueryableHandler(queryable); | ||||||
|  |             if (handler == null) | ||||||
|  |                 throw new NoAsyncQueryableHandlerServiceWasRegisteredForThisProviderException(); | ||||||
|  | 
 | ||||||
|  |             return handler; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public IAsyncQueryableHandlerService GetAsyncQueryableHandler<T>(IQueryable<T> queryable) | ||||||
|  |         { | ||||||
|  |             var handler = AsyncQueryableFactories.FirstOrDefault(t => t.CanHandle(queryable)); | ||||||
|  |             return handler; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public Task<long> LongCountAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)) | ||||||
|  |             => GetAsyncQueryableHandlerOrThrow(queryable).LongCountAsync(queryable, cancellationToken); | ||||||
|  | 
 | ||||||
|  |         public Task<List<T>> ToListAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)) | ||||||
|  |             => GetAsyncQueryableHandlerOrThrow(queryable).ToListAsync(queryable, cancellationToken); | ||||||
|  | 
 | ||||||
|  |         public Task<bool> AnyAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken)) | ||||||
|  |             => GetAsyncQueryableHandlerOrThrow(queryable).AnyAsync(queryable, predicate, cancellationToken); | ||||||
|  | 
 | ||||||
|  |         public Task<bool> AnyAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default(CancellationToken)) | ||||||
|  |             => GetAsyncQueryableHandlerOrThrow(queryable).AnyAsync(queryable, cancellationToken); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,12 @@ | |||||||
|  | using System; | ||||||
|  | using System.Runtime.Serialization; | ||||||
|  | 
 | ||||||
|  | namespace PoweredSoft.Data | ||||||
|  | { | ||||||
|  |     public class NoAsyncQueryableHandlerServiceWasRegisteredForThisProviderException : Exception | ||||||
|  |     { | ||||||
|  |         public NoAsyncQueryableHandlerServiceWasRegisteredForThisProviderException() : base("No AsyncQueryableHandlerService was registered for this queryable provider") | ||||||
|  |         { | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										31
									
								
								PoweredSoft.Data/PoweredSoft.Data.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								PoweredSoft.Data/PoweredSoft.Data.csproj
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | <Project Sdk="Microsoft.NET.Sdk"> | ||||||
|  | 
 | ||||||
|  |   <PropertyGroup> | ||||||
|  |     <TargetFramework>netstandard2.0</TargetFramework> | ||||||
|  |     <GeneratePackageOnBuild>True</GeneratePackageOnBuild> | ||||||
|  |     <Copyright>Powered Softwares Inc.</Copyright> | ||||||
|  |     <PackageLicenseUrl>MIT</PackageLicenseUrl> | ||||||
|  |     <PackageProjectUrl>https://github.com/PoweredSoft/Data</PackageProjectUrl> | ||||||
|  |     <RepositoryUrl>https://github.com/PoweredSoft/Data</RepositoryUrl> | ||||||
|  |     <RepositoryType>github</RepositoryType> | ||||||
|  |     <PackageTags>async,queryable,handler,service,di</PackageTags> | ||||||
|  |     <Version>1.1.0</Version> | ||||||
|  |     <PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl> | ||||||
|  |     <Product>PoweredSoft.Data</Product> | ||||||
|  |     <Description>Library to abstract orm.</Description> | ||||||
|  |     <PackageId>PoweredSoft.Data</PackageId> | ||||||
|  |     <PackageReleaseNotes>N/A</PackageReleaseNotes> | ||||||
|  |     <PackageRequireLicenseAcceptance>False</PackageRequireLicenseAcceptance> | ||||||
|  |     <Company>PoweredSoft</Company> | ||||||
|  |     <Authors>David Lebee</Authors> | ||||||
|  |   </PropertyGroup> | ||||||
|  | 
 | ||||||
|  |   <ItemGroup> | ||||||
|  |     <ProjectReference Include="..\PoweredSoft.Data.Core\PoweredSoft.Data.Core.csproj" /> | ||||||
|  |   </ItemGroup> | ||||||
|  | 
 | ||||||
|  |   <ItemGroup> | ||||||
|  |     <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" /> | ||||||
|  |   </ItemGroup> | ||||||
|  | 
 | ||||||
|  | </Project> | ||||||
							
								
								
									
										18
									
								
								PoweredSoft.Data/ServiceCollectionExtensions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								PoweredSoft.Data/ServiceCollectionExtensions.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | |||||||
|  | using Microsoft.Extensions.DependencyInjection; | ||||||
|  | using Microsoft.Extensions.DependencyInjection.Extensions; | ||||||
|  | using PoweredSoft.Data.Core; | ||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Text; | ||||||
|  | 
 | ||||||
|  | namespace PoweredSoft.Data | ||||||
|  | { | ||||||
|  |     public static class ServiceCollectionExtensions | ||||||
|  |     { | ||||||
|  |         public static IServiceCollection AddPoweredSoftDataServices(this IServiceCollection services) | ||||||
|  |         { | ||||||
|  |             services.TryAddTransient<IAsyncQueryableService, AsyncQueryableService>(); | ||||||
|  |             return services; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user