From e99748addca417ae66b3a83cbe69ffa9f4aa7d8c Mon Sep 17 00:00:00 2001 From: Hassan Habib Date: Tue, 28 Feb 2023 13:27:40 -0800 Subject: [PATCH] POC: Working Prototype --- .../Clients/Extensions/ClientTests.cs | 37 +++++++++ .../Extensions/ODataEnumerableClient.cs | 78 +++++++++++++++++++ .../OExpressions/OExpressionService.cs | 3 +- 3 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 OData.Neo.Core.Tests.Unit/Clients/Extensions/ClientTests.cs create mode 100644 OData.Neo.Core/Clients/Extensions/ODataEnumerableClient.cs diff --git a/OData.Neo.Core.Tests.Unit/Clients/Extensions/ClientTests.cs b/OData.Neo.Core.Tests.Unit/Clients/Extensions/ClientTests.cs new file mode 100644 index 0000000..8018567 --- /dev/null +++ b/OData.Neo.Core.Tests.Unit/Clients/Extensions/ClientTests.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OData.Neo.Core.Clients.Extensions; +using Xunit; + +namespace OData.Neo.Core.Tests.Unit.Clients.Extensions +{ + public class ClientTests + { + [Fact] + public async Task ShouldFilterStudent() + { + // given + var students = new List + { + new Student { Id = Guid.NewGuid(), Name = "John" }, + new Student { Id = Guid.NewGuid(), Name = "Mary" }, + new Student { Id = Guid.NewGuid(), Name = "Peter" } + }.AsQueryable(); + + var filteredStuff = + await students.ApplyODataQueryAsync( + "$select=Name"); + + Assert.True(true); + } + + public class Student + { + public Guid Id { get; set; } + public string Name { get; set; } + } + } +} diff --git a/OData.Neo.Core/Clients/Extensions/ODataEnumerableClient.cs b/OData.Neo.Core/Clients/Extensions/ODataEnumerableClient.cs new file mode 100644 index 0000000..62be6f6 --- /dev/null +++ b/OData.Neo.Core/Clients/Extensions/ODataEnumerableClient.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using OData.Neo.Core.Brokers.Expressions; +using OData.Neo.Core.Brokers.SqlQueries; +using OData.Neo.Core.Services.Coordinations.OQueries; +using OData.Neo.Core.Services.Foundations.OExpressions; +using OData.Neo.Core.Services.Foundations.OQueries; +using OData.Neo.Core.Services.Foundations.OSqls; +using OData.Neo.Core.Services.Foundations.OTokenizations; +using OData.Neo.Core.Services.Foundations.Projections; +using OData.Neo.Core.Services.Foundations.Tokenizations; +using OData.Neo.Core.Services.Orchestrations.OQueries; +using OData.Neo.Core.Services.Orchestrations.OTokenizations; + +namespace OData.Neo.Core.Clients.Extensions +{ + public static class ODataEnumerableClient + { + public static async ValueTask ApplyODataQueryAsync( + this IQueryable queryable, + string odataQuery) where T : class + { + var otokenizationService = new OTokenizationService(); + var projectionService = new ProjectionService(); + var tokenizationService = new TokenizationService(); + + var oTokenizationOrchestrationService = + new OTokenizationOrchestrationService( + tokenizationService, + projectionService, + otokenizationService); + + var expressionBroker = new ExpressionBroker(); + var sqlQueryBroker = new SqlQueryBroker(); + + var oExpressionService = new OExpressionService(expressionBroker); + var oQueryService = new OQueryService(sqlQueryBroker); + var oSqlService = new OSqlService(sqlQueryBroker); + + var oQueryOrchestrationService = + new OQueryOrchestrationService( + oExpressionService, + oQueryService, + oSqlService); + + var oQueryCoordinationService = new OQueryCoordinationService( + oTokenizationOrchestrationService, + oQueryOrchestrationService); + + Expression oQueryExpression = + await oQueryCoordinationService + .ProcessOQueryAsync(odataQuery); + + return Execute(queryable, oQueryExpression); + } + + public static IQueryable Execute(IQueryable sources, Expression exp) + { + MethodCallExpression call = exp as MethodCallExpression; + + // Select(...) + MethodInfo methodInfo = call.Method; + + UnaryExpression unary = call.Arguments[1] as UnaryExpression; + + LambdaExpression lambda = unary.Operand as LambdaExpression; + + // Delegate delegateFunc = lambda.Compile(); + + return methodInfo.Invoke(null, new object[] { sources, lambda }) as IQueryable; + } + } +} diff --git a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs index 6d69079..218cddd 100644 --- a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs +++ b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs @@ -44,7 +44,8 @@ private string CovertToLinqExp(OToken token) { string properties = string.Join( separator: ",", - values: child.Children.Select(child => $"obj.{child.RawValue}")); + values: child.Children.Where(c => c.ProjectedType == Models.ProjectedTokens.ProjectedTokenType.Property) + .Select(c => $"obj.{c.RawValue}")); stringBuilder.Append($"Select(obj => new {{{properties}}})"); }