Skip to content

Commit

Permalink
Adding aggregate(CountAsync/SumAsync etc.) extensions for LINQ query (#…
Browse files Browse the repository at this point in the history
…729)

* initial commit

* adding change log

* updating DotNetSDKAPI.json

* reolving comments

* updating pr heading in changelog

* fixing merging issue
  • Loading branch information
simplynaveen20 authored and kirankumarkolli committed Aug 27, 2019
1 parent 2f59b10 commit 2fa8713
Show file tree
Hide file tree
Showing 8 changed files with 977 additions and 397 deletions.
543 changes: 543 additions & 0 deletions Microsoft.Azure.Cosmos/src/Linq/CosmosLinqExtensions.cs

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions Microsoft.Azure.Cosmos/src/Linq/CosmosLinqQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,18 @@ Task<DocumentFeedResponse<dynamic>> IDocumentQuery<T>.ExecuteNextAsync(Cancellat
throw new NotImplementedException();
}

internal async Task<IList<T>> AggregateResultAsync(CancellationToken cancellationToken = default(CancellationToken))
{
List<T> result = new List<T>();
FeedIterator<T> localFeedIterator = this.CreateFeedIterator(false);
while (localFeedIterator.HasMoreResults)
{
FeedResponse<T> response = await localFeedIterator.ReadNextAsync();
result.AddRange(response);
}
return result;
}

private FeedIterator CreateStreamIterator(bool isContinuationExcpected)
{
SqlQuerySpec querySpec = DocumentQueryEvaluator.Evaluate(this.Expression, this.serializationOptions);
Expand Down
22 changes: 22 additions & 0 deletions Microsoft.Azure.Cosmos/src/Linq/CosmosLinqQueryProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
namespace Microsoft.Azure.Cosmos.Linq
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos.Linq;

/// <summary>
Expand Down Expand Up @@ -105,5 +108,24 @@ public object Execute(Expression expression)
this.onExecuteScalarQueryCallback?.Invoke(cosmosLINQQuery);
return cosmosLINQQuery.ToList().FirstOrDefault();
}

public async Task<TResult> ExecuteAggregateAsync<TResult>(
Expression expression,
CancellationToken cancellationToken = default(CancellationToken))
{
Type cosmosQueryType = typeof(CosmosLinqQuery<bool>).GetGenericTypeDefinition().MakeGenericType(typeof(TResult));
CosmosLinqQuery<TResult> cosmosLINQQuery = (CosmosLinqQuery<TResult>)Activator.CreateInstance(
cosmosQueryType,
this.container,
this.responseFactory,
this.queryClient,
this.continuationToken,
this.cosmosQueryRequestOptions,
expression,
this.allowSynchronousQueryExecution,
this.serializationOptions);
IList<TResult> result = await cosmosLINQQuery.AggregateResultAsync();
return result.FirstOrDefault();
}
}
}
396 changes: 0 additions & 396 deletions Microsoft.Azure.Cosmos/src/Linq/DocumentQueryable.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Linq.Dynamic;
using System.Threading.Tasks;
Expand Down Expand Up @@ -105,7 +107,7 @@ public async Task ItemLinqReadFeedTest(bool useStatelessIterator)
{
lastContinuationToken = responseMessage.Headers.ContinuationToken;

System.Collections.ObjectModel.Collection<ToDoActivity> items = TestCommon.Serializer.FromStream<CosmosFeedResponseUtil<ToDoActivity>>(responseMessage.Content).Data;
Collection<ToDoActivity> items = TestCommon.Serializer.FromStream<CosmosFeedResponseUtil<ToDoActivity>>(responseMessage.Content).Data;
foreach (ToDoActivity toDoActivity in items)
{
if (itemIds.Contains(toDoActivity.id))
Expand Down Expand Up @@ -255,6 +257,92 @@ public async Task ItemLINQQueryWithContinuationTokenTest()
}

[TestMethod]
public async Task QueryableExtentionFunctionsTest()
{
//Creating items for query.
IList<ToDoActivity> itemList = await ToDoActivity.CreateRandomItems(container: this.Container, pkCount: 10, perPKItemCount: 1, randomPartitionKey: true);

IOrderedQueryable<ToDoActivity> linqQueryable = this.Container.GetItemLinqQueryable<ToDoActivity>();

int count = await linqQueryable.CountAsync();
Assert.AreEqual(10, count);

int intSum = await linqQueryable.Select(item => item.taskNum).SumAsync();
Assert.AreEqual(420, intSum);

int? intNullableSum = await linqQueryable.Select(item => item.taskNum).SumAsync();
Assert.AreEqual(420, intNullableSum);

float floatSum = await linqQueryable.Select(item => (float)item.taskNum).SumAsync();
Assert.AreEqual(420, intSum);

float? floatNullableSum = await linqQueryable.Select(item => (float?)item.taskNum).SumAsync();
Assert.AreEqual(420, intNullableSum);

double doubleSum = await linqQueryable.Select(item => (double)item.taskNum).SumAsync();
Assert.AreEqual(420, doubleSum);

double? doubleNullableSum = await linqQueryable.Select(item => (double?)item.taskNum).SumAsync();
Assert.AreEqual(420, doubleNullableSum);

long longSum = await linqQueryable.Select(item => (long)item.taskNum).SumAsync();
Assert.AreEqual(420, longSum);

long? longNullableSum = await linqQueryable.Select(item => (long?)item.taskNum).SumAsync();
Assert.AreEqual(420, longNullableSum);

decimal decimalSum = await linqQueryable.Select(item => (decimal)item.taskNum).SumAsync();
Assert.AreEqual(420, decimalSum);

decimal? decimalNullableSum = await linqQueryable.Select(item => (decimal?)item.taskNum).SumAsync();
Assert.AreEqual(420, decimalNullableSum);

double intToDoubleAvg = await linqQueryable.Select(item => item.taskNum).AverageAsync();
Assert.AreEqual(42, intToDoubleAvg);

double? intToDoubleNulableAvg = await linqQueryable.Select(item => item.taskNum).AverageAsync();
Assert.AreEqual(42, intToDoubleNulableAvg);

float floatAvg = await linqQueryable.Select(item => (float)item.taskNum).AverageAsync();
Assert.AreEqual(42, floatAvg);

float? floatNullableAvg = await linqQueryable.Select(item => (float?)item.taskNum).AverageAsync();
Assert.AreEqual(42, floatNullableAvg);

double doubleAvg = await linqQueryable.Select(item => (double)item.taskNum).AverageAsync();
Assert.AreEqual(42, doubleAvg);

double? doubleNullableAvg = await linqQueryable.Select(item => (double?)item.taskNum).AverageAsync();
Assert.AreEqual(42, doubleNullableAvg);

double longToDoubleAvg = await linqQueryable.Select(item => (long)item.taskNum).AverageAsync();
Assert.AreEqual(42, longToDoubleAvg);

double? longToNullableDoubleAvg = await linqQueryable.Select(item => (long?)item.taskNum).AverageAsync();
Assert.AreEqual(42, longToNullableDoubleAvg);

decimal decimalAvg = await linqQueryable.Select(item => (decimal)item.taskNum).AverageAsync();
Assert.AreEqual(42, decimalAvg);

decimal? decimalNullableAvg = await linqQueryable.Select(item => (decimal?)item.taskNum).AverageAsync();
Assert.AreEqual(42, decimalNullableAvg);

//Adding more items to test min and max function
ToDoActivity toDoActivity = ToDoActivity.CreateRandomToDoActivity();
toDoActivity.taskNum = 20;
toDoActivity.id = "minTaskNum";
await this.Container.CreateItemAsync(toDoActivity, new PartitionKey(toDoActivity.status));
toDoActivity.taskNum = 100;
toDoActivity.id = "maxTaskNum";
await this.Container.CreateItemAsync(toDoActivity, new PartitionKey(toDoActivity.status));

int minTaskNum = await linqQueryable.Select(item => item.taskNum).MinAsync();
Assert.AreEqual(20, minTaskNum);

int maxTaskNum = await linqQueryable.Select(item => item.taskNum).MaxAsync();
Assert.AreEqual(100, maxTaskNum);
}

[DataRow(false)]
[DataRow(true)]
public async Task ItemLINQWithCamelCaseSerializerOptions(bool isGatewayMode)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3057,6 +3057,167 @@
"ExtensionAttribute"
],
"MethodInfo": "Microsoft.Azure.Cosmos.QueryDefinition ToQueryDefinition[T](System.Linq.IQueryable`1[T])"
},
"System.Threading.Tasks.Task`1[System.Decimal] AverageAsync(System.Linq.IQueryable`1[System.Decimal], System.Threading.CancellationToken)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
"MethodInfo": "System.Threading.Tasks.Task`1[System.Decimal] AverageAsync(System.Linq.IQueryable`1[System.Decimal], System.Threading.CancellationToken)"
},
"System.Threading.Tasks.Task`1[System.Decimal] SumAsync(System.Linq.IQueryable`1[System.Decimal], System.Threading.CancellationToken)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
"MethodInfo": "System.Threading.Tasks.Task`1[System.Decimal] SumAsync(System.Linq.IQueryable`1[System.Decimal], System.Threading.CancellationToken)"
},
"System.Threading.Tasks.Task`1[System.Double] AverageAsync(System.Linq.IQueryable`1[System.Double], System.Threading.CancellationToken)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
"MethodInfo": "System.Threading.Tasks.Task`1[System.Double] AverageAsync(System.Linq.IQueryable`1[System.Double], System.Threading.CancellationToken)"
},
"System.Threading.Tasks.Task`1[System.Double] AverageAsync(System.Linq.IQueryable`1[System.Int32], System.Threading.CancellationToken)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
"MethodInfo": "System.Threading.Tasks.Task`1[System.Double] AverageAsync(System.Linq.IQueryable`1[System.Int32], System.Threading.CancellationToken)"
},
"System.Threading.Tasks.Task`1[System.Double] AverageAsync(System.Linq.IQueryable`1[System.Int64], System.Threading.CancellationToken)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
"MethodInfo": "System.Threading.Tasks.Task`1[System.Double] AverageAsync(System.Linq.IQueryable`1[System.Int64], System.Threading.CancellationToken)"
},
"System.Threading.Tasks.Task`1[System.Double] SumAsync(System.Linq.IQueryable`1[System.Double], System.Threading.CancellationToken)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
"MethodInfo": "System.Threading.Tasks.Task`1[System.Double] SumAsync(System.Linq.IQueryable`1[System.Double], System.Threading.CancellationToken)"
},
"System.Threading.Tasks.Task`1[System.Int32] CountAsync[TSource](System.Linq.IQueryable`1[TSource], System.Threading.CancellationToken)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
"MethodInfo": "System.Threading.Tasks.Task`1[System.Int32] CountAsync[TSource](System.Linq.IQueryable`1[TSource], System.Threading.CancellationToken)"
},
"System.Threading.Tasks.Task`1[System.Int32] SumAsync(System.Linq.IQueryable`1[System.Int32], System.Threading.CancellationToken)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
"MethodInfo": "System.Threading.Tasks.Task`1[System.Int32] SumAsync(System.Linq.IQueryable`1[System.Int32], System.Threading.CancellationToken)"
},
"System.Threading.Tasks.Task`1[System.Int64] SumAsync(System.Linq.IQueryable`1[System.Int64], System.Threading.CancellationToken)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
"MethodInfo": "System.Threading.Tasks.Task`1[System.Int64] SumAsync(System.Linq.IQueryable`1[System.Int64], System.Threading.CancellationToken)"
},
"System.Threading.Tasks.Task`1[System.Nullable`1[System.Decimal]] AverageAsync(System.Linq.IQueryable`1[System.Nullable`1[System.Decimal]], System.Threading.CancellationToken)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
"MethodInfo": "System.Threading.Tasks.Task`1[System.Nullable`1[System.Decimal]] AverageAsync(System.Linq.IQueryable`1[System.Nullable`1[System.Decimal]], System.Threading.CancellationToken)"
},
"System.Threading.Tasks.Task`1[System.Nullable`1[System.Decimal]] SumAsync(System.Linq.IQueryable`1[System.Nullable`1[System.Decimal]], System.Threading.CancellationToken)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
"MethodInfo": "System.Threading.Tasks.Task`1[System.Nullable`1[System.Decimal]] SumAsync(System.Linq.IQueryable`1[System.Nullable`1[System.Decimal]], System.Threading.CancellationToken)"
},
"System.Threading.Tasks.Task`1[System.Nullable`1[System.Double]] AverageAsync(System.Linq.IQueryable`1[System.Nullable`1[System.Double]], System.Threading.CancellationToken)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
"MethodInfo": "System.Threading.Tasks.Task`1[System.Nullable`1[System.Double]] AverageAsync(System.Linq.IQueryable`1[System.Nullable`1[System.Double]], System.Threading.CancellationToken)"
},
"System.Threading.Tasks.Task`1[System.Nullable`1[System.Double]] AverageAsync(System.Linq.IQueryable`1[System.Nullable`1[System.Int32]], System.Threading.CancellationToken)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
"MethodInfo": "System.Threading.Tasks.Task`1[System.Nullable`1[System.Double]] AverageAsync(System.Linq.IQueryable`1[System.Nullable`1[System.Int32]], System.Threading.CancellationToken)"
},
"System.Threading.Tasks.Task`1[System.Nullable`1[System.Double]] AverageAsync(System.Linq.IQueryable`1[System.Nullable`1[System.Int64]], System.Threading.CancellationToken)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
"MethodInfo": "System.Threading.Tasks.Task`1[System.Nullable`1[System.Double]] AverageAsync(System.Linq.IQueryable`1[System.Nullable`1[System.Int64]], System.Threading.CancellationToken)"
},
"System.Threading.Tasks.Task`1[System.Nullable`1[System.Double]] SumAsync(System.Linq.IQueryable`1[System.Nullable`1[System.Double]], System.Threading.CancellationToken)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
"MethodInfo": "System.Threading.Tasks.Task`1[System.Nullable`1[System.Double]] SumAsync(System.Linq.IQueryable`1[System.Nullable`1[System.Double]], System.Threading.CancellationToken)"
},
"System.Threading.Tasks.Task`1[System.Nullable`1[System.Int32]] SumAsync(System.Linq.IQueryable`1[System.Nullable`1[System.Int32]], System.Threading.CancellationToken)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
"MethodInfo": "System.Threading.Tasks.Task`1[System.Nullable`1[System.Int32]] SumAsync(System.Linq.IQueryable`1[System.Nullable`1[System.Int32]], System.Threading.CancellationToken)"
},
"System.Threading.Tasks.Task`1[System.Nullable`1[System.Int64]] SumAsync(System.Linq.IQueryable`1[System.Nullable`1[System.Int64]], System.Threading.CancellationToken)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
"MethodInfo": "System.Threading.Tasks.Task`1[System.Nullable`1[System.Int64]] SumAsync(System.Linq.IQueryable`1[System.Nullable`1[System.Int64]], System.Threading.CancellationToken)"
},
"System.Threading.Tasks.Task`1[System.Nullable`1[System.Single]] AverageAsync(System.Linq.IQueryable`1[System.Nullable`1[System.Single]], System.Threading.CancellationToken)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
"MethodInfo": "System.Threading.Tasks.Task`1[System.Nullable`1[System.Single]] AverageAsync(System.Linq.IQueryable`1[System.Nullable`1[System.Single]], System.Threading.CancellationToken)"
},
"System.Threading.Tasks.Task`1[System.Nullable`1[System.Single]] SumAsync(System.Linq.IQueryable`1[System.Nullable`1[System.Single]], System.Threading.CancellationToken)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
"MethodInfo": "System.Threading.Tasks.Task`1[System.Nullable`1[System.Single]] SumAsync(System.Linq.IQueryable`1[System.Nullable`1[System.Single]], System.Threading.CancellationToken)"
},
"System.Threading.Tasks.Task`1[System.Single] AverageAsync(System.Linq.IQueryable`1[System.Single], System.Threading.CancellationToken)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
"MethodInfo": "System.Threading.Tasks.Task`1[System.Single] AverageAsync(System.Linq.IQueryable`1[System.Single], System.Threading.CancellationToken)"
},
"System.Threading.Tasks.Task`1[System.Single] SumAsync(System.Linq.IQueryable`1[System.Single], System.Threading.CancellationToken)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
"MethodInfo": "System.Threading.Tasks.Task`1[System.Single] SumAsync(System.Linq.IQueryable`1[System.Single], System.Threading.CancellationToken)"
},
"System.Threading.Tasks.Task`1[TSource] MaxAsync[TSource](System.Linq.IQueryable`1[TSource], System.Threading.CancellationToken)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
"MethodInfo": "System.Threading.Tasks.Task`1[TSource] MaxAsync[TSource](System.Linq.IQueryable`1[TSource], System.Threading.CancellationToken)"
},
"System.Threading.Tasks.Task`1[TSource] MinAsync[TSource](System.Linq.IQueryable`1[TSource], System.Threading.CancellationToken)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
"MethodInfo": "System.Threading.Tasks.Task`1[TSource] MinAsync[TSource](System.Linq.IQueryable`1[TSource], System.Threading.CancellationToken)"
}
},
"NestedTypes": {}
Expand Down
Loading

0 comments on commit 2fa8713

Please sign in to comment.