Skip to content

Commit ecce6cf

Browse files
asketagarwalj82w
andauthored
LINQ: Adds camelCase support to GetItemLinqQueryable() as optional parameter (#2220)
* Adding camelcase flag to GetItemLinqQueryable * Changing bool to CosmosNamingPropertyPolicy * Improving logic and adding tests * Adding new contract for CosmosLinqSerializerOptions * Changing public contract * Changing namespace for LinqSerlizerOptions Co-authored-by: j82w <[email protected]>
1 parent 816cc5a commit ecce6cf

14 files changed

+181
-49
lines changed

Microsoft.Azure.Cosmos/src/Linq/CosmosLinqQuery.cs

+10-10
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ internal sealed class CosmosLinqQuery<T> : IDocumentQuery<T>, IOrderedQueryable<
3232
private readonly QueryRequestOptions cosmosQueryRequestOptions;
3333
private readonly bool allowSynchronousQueryExecution = false;
3434
private readonly string continuationToken;
35-
private readonly CosmosSerializationOptions serializationOptions;
35+
private readonly CosmosLinqSerializerOptions linqSerializationOptions;
3636

3737
public CosmosLinqQuery(
3838
ContainerInternal container,
@@ -42,7 +42,7 @@ public CosmosLinqQuery(
4242
QueryRequestOptions cosmosQueryRequestOptions,
4343
Expression expression,
4444
bool allowSynchronousQueryExecution,
45-
CosmosSerializationOptions serializationOptions = null)
45+
CosmosLinqSerializerOptions linqSerializationOptions = null)
4646
{
4747
this.container = container ?? throw new ArgumentNullException(nameof(container));
4848
this.responseFactory = responseFactory ?? throw new ArgumentNullException(nameof(responseFactory));
@@ -52,7 +52,7 @@ public CosmosLinqQuery(
5252
this.Expression = expression ?? Expression.Constant(this);
5353
this.allowSynchronousQueryExecution = allowSynchronousQueryExecution;
5454
this.correlatedActivityId = Guid.NewGuid();
55-
this.serializationOptions = serializationOptions;
55+
this.linqSerializationOptions = linqSerializationOptions;
5656

5757
this.queryProvider = new CosmosLinqQueryProvider(
5858
container,
@@ -62,7 +62,7 @@ public CosmosLinqQuery(
6262
cosmosQueryRequestOptions,
6363
this.allowSynchronousQueryExecution,
6464
this.queryClient.OnExecuteScalarQueryCallback,
65-
this.serializationOptions);
65+
this.linqSerializationOptions);
6666
}
6767

6868
public CosmosLinqQuery(
@@ -72,7 +72,7 @@ public CosmosLinqQuery(
7272
string continuationToken,
7373
QueryRequestOptions cosmosQueryRequestOptions,
7474
bool allowSynchronousQueryExecution,
75-
CosmosSerializationOptions serializationOptions = null)
75+
CosmosLinqSerializerOptions linqSerializerOptions = null)
7676
: this(
7777
container,
7878
responseFactory,
@@ -81,7 +81,7 @@ public CosmosLinqQuery(
8181
cosmosQueryRequestOptions,
8282
null,
8383
allowSynchronousQueryExecution,
84-
serializationOptions)
84+
linqSerializerOptions)
8585
{
8686
}
8787

@@ -133,7 +133,7 @@ IEnumerator IEnumerable.GetEnumerator()
133133

134134
public override string ToString()
135135
{
136-
SqlQuerySpec querySpec = DocumentQueryEvaluator.Evaluate(this.Expression, this.serializationOptions);
136+
SqlQuerySpec querySpec = DocumentQueryEvaluator.Evaluate(this.Expression, this.linqSerializationOptions);
137137
if (querySpec != null)
138138
{
139139
return JsonConvert.SerializeObject(querySpec);
@@ -144,7 +144,7 @@ public override string ToString()
144144

145145
public QueryDefinition ToQueryDefinition(IDictionary<object, string> parameters = null)
146146
{
147-
SqlQuerySpec querySpec = DocumentQueryEvaluator.Evaluate(this.Expression, this.serializationOptions, parameters);
147+
SqlQuerySpec querySpec = DocumentQueryEvaluator.Evaluate(this.Expression, this.linqSerializationOptions, parameters);
148148
return QueryDefinition.CreateFromQuerySpec(querySpec);
149149
}
150150

@@ -201,7 +201,7 @@ internal async Task<Response<T>> AggregateResultAsync(CancellationToken cancella
201201

202202
private FeedIteratorInternal CreateStreamIterator(bool isContinuationExcpected)
203203
{
204-
SqlQuerySpec querySpec = DocumentQueryEvaluator.Evaluate(this.Expression, this.serializationOptions);
204+
SqlQuerySpec querySpec = DocumentQueryEvaluator.Evaluate(this.Expression, this.linqSerializationOptions);
205205

206206
return this.container.GetItemQueryStreamIteratorInternal(
207207
sqlQuerySpec: querySpec,
@@ -213,7 +213,7 @@ private FeedIteratorInternal CreateStreamIterator(bool isContinuationExcpected)
213213

214214
private FeedIterator<T> CreateFeedIterator(bool isContinuationExpected)
215215
{
216-
SqlQuerySpec querySpec = DocumentQueryEvaluator.Evaluate(this.Expression, this.serializationOptions);
216+
SqlQuerySpec querySpec = DocumentQueryEvaluator.Evaluate(this.Expression, this.linqSerializationOptions);
217217

218218
FeedIteratorInternal streamIterator = this.CreateStreamIterator(isContinuationExpected);
219219
return new FeedIteratorInlineCore<T>(new FeedIteratorCore<T>(

Microsoft.Azure.Cosmos/src/Linq/CosmosLinqQueryProvider.cs

+9-8
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ namespace Microsoft.Azure.Cosmos.Linq
1010
using System.Linq.Expressions;
1111
using System.Threading;
1212
using System.Threading.Tasks;
13+
using Microsoft.Azure.Cosmos.Serializer;
1314

1415
/// <summary>
1516
/// This class serve as LINQ query provider implementing IQueryProvider.
@@ -23,7 +24,7 @@ internal sealed class CosmosLinqQueryProvider : IQueryProvider
2324
private readonly bool allowSynchronousQueryExecution;
2425
private readonly Action<IQueryable> onExecuteScalarQueryCallback;
2526
private readonly string continuationToken;
26-
private readonly CosmosSerializationOptions serializationOptions;
27+
private readonly CosmosLinqSerializerOptions linqSerializerOptions;
2728

2829
public CosmosLinqQueryProvider(
2930
ContainerInternal container,
@@ -33,7 +34,7 @@ public CosmosLinqQueryProvider(
3334
QueryRequestOptions cosmosQueryRequestOptions,
3435
bool allowSynchronousQueryExecution,
3536
Action<IQueryable> onExecuteScalarQueryCallback = null,
36-
CosmosSerializationOptions serializationOptions = null)
37+
CosmosLinqSerializerOptions linqSerializerOptions = null)
3738
{
3839
this.container = container;
3940
this.responseFactory = responseFactory;
@@ -42,7 +43,7 @@ public CosmosLinqQueryProvider(
4243
this.cosmosQueryRequestOptions = cosmosQueryRequestOptions;
4344
this.allowSynchronousQueryExecution = allowSynchronousQueryExecution;
4445
this.onExecuteScalarQueryCallback = onExecuteScalarQueryCallback;
45-
this.serializationOptions = serializationOptions;
46+
this.linqSerializerOptions = linqSerializerOptions;
4647
}
4748

4849
public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
@@ -55,7 +56,7 @@ public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
5556
this.cosmosQueryRequestOptions,
5657
expression,
5758
this.allowSynchronousQueryExecution,
58-
this.serializationOptions);
59+
this.linqSerializerOptions);
5960
}
6061

6162
public IQueryable CreateQuery(Expression expression)
@@ -71,7 +72,7 @@ public IQueryable CreateQuery(Expression expression)
7172
this.cosmosQueryRequestOptions,
7273
expression,
7374
this.allowSynchronousQueryExecution,
74-
this.serializationOptions);
75+
this.linqSerializerOptions);
7576
}
7677

7778
public TResult Execute<TResult>(Expression expression)
@@ -86,7 +87,7 @@ public TResult Execute<TResult>(Expression expression)
8687
this.cosmosQueryRequestOptions,
8788
expression,
8889
this.allowSynchronousQueryExecution,
89-
this.serializationOptions);
90+
this.linqSerializerOptions);
9091
this.onExecuteScalarQueryCallback?.Invoke(cosmosLINQQuery);
9192
return cosmosLINQQuery.ToList().FirstOrDefault();
9293
}
@@ -103,7 +104,7 @@ public object Execute(Expression expression)
103104
this.continuationToken,
104105
this.cosmosQueryRequestOptions,
105106
this.allowSynchronousQueryExecution,
106-
this.serializationOptions);
107+
this.linqSerializerOptions);
107108
this.onExecuteScalarQueryCallback?.Invoke(cosmosLINQQuery);
108109
return cosmosLINQQuery.ToList().FirstOrDefault();
109110
}
@@ -122,7 +123,7 @@ public Task<Response<TResult>> ExecuteAggregateAsync<TResult>(
122123
this.cosmosQueryRequestOptions,
123124
expression,
124125
this.allowSynchronousQueryExecution,
125-
this.serializationOptions);
126+
this.linqSerializerOptions);
126127
return TaskHelper.RunInlineIfNeededAsync(() => cosmosLINQQuery.AggregateResultAsync(cancellationToken));
127128
}
128129
}

Microsoft.Azure.Cosmos/src/Linq/DocumentQueryEvaluator.cs

+5-4
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@ namespace Microsoft.Azure.Cosmos.Linq
99
using System.Globalization;
1010
using System.Linq.Expressions;
1111
using Microsoft.Azure.Cosmos.Query.Core;
12+
using Microsoft.Azure.Cosmos.Serializer;
1213

1314
internal static class DocumentQueryEvaluator
1415
{
1516
private const string SQLMethod = "AsSQL";
1617

1718
public static SqlQuerySpec Evaluate(
1819
Expression expression,
19-
CosmosSerializationOptions serializationOptions = null,
20+
CosmosLinqSerializerOptions linqSerializerOptions = null,
2021
IDictionary<object, string> parameters = null)
2122
{
2223
switch (expression.NodeType)
@@ -27,7 +28,7 @@ public static SqlQuerySpec Evaluate(
2728
}
2829
case ExpressionType.Call:
2930
{
30-
return DocumentQueryEvaluator.HandleMethodCallExpression((MethodCallExpression)expression, parameters, serializationOptions);
31+
return DocumentQueryEvaluator.HandleMethodCallExpression((MethodCallExpression)expression, parameters, linqSerializerOptions);
3132
}
3233

3334
default:
@@ -75,7 +76,7 @@ private static SqlQuerySpec HandleEmptyQuery(ConstantExpression expression)
7576
private static SqlQuerySpec HandleMethodCallExpression(
7677
MethodCallExpression expression,
7778
IDictionary<object, string> parameters,
78-
CosmosSerializationOptions serializationOptions = null)
79+
CosmosLinqSerializerOptions linqSerializerOptions = null)
7980
{
8081
if (DocumentQueryEvaluator.IsTransformExpression(expression))
8182
{
@@ -92,7 +93,7 @@ private static SqlQuerySpec HandleMethodCallExpression(
9293
}
9394
}
9495

95-
return SqlTranslator.TranslateQuery(expression, serializationOptions, parameters);
96+
return SqlTranslator.TranslateQuery(expression, linqSerializerOptions, parameters);
9697
}
9798

9899
/// <summary>

Microsoft.Azure.Cosmos/src/Linq/ExpressionToSQL.cs

+7-6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ namespace Microsoft.Azure.Cosmos.Linq
1515
using System.Reflection;
1616
using Microsoft.Azure.Cosmos.CosmosElements;
1717
using Microsoft.Azure.Cosmos.CosmosElements.Numbers;
18+
using Microsoft.Azure.Cosmos.Serializer;
1819
using Microsoft.Azure.Cosmos.Spatial;
1920
using Microsoft.Azure.Cosmos.SqlObjects;
2021
using Microsoft.Azure.Documents;
@@ -86,14 +87,14 @@ public static class LinqMethods
8687
/// </summary>
8788
/// <param name="inputExpression">An Expression representing a Query on a IDocumentQuery object.</param>
8889
/// <param name="parameters">Optional dictionary for parameter name and value</param>
89-
/// <param name="serializationOptions">Optional serializer options.</param>
90+
/// <param name="linqSerializerOptions">Optional serializer options.</param>
9091
/// <returns>The corresponding SQL query.</returns>
9192
public static SqlQuery TranslateQuery(
9293
Expression inputExpression,
9394
IDictionary<object, string> parameters,
94-
CosmosSerializationOptions serializationOptions)
95+
CosmosLinqSerializerOptions linqSerializerOptions)
9596
{
96-
TranslationContext context = new TranslationContext(serializationOptions, parameters);
97+
TranslationContext context = new TranslationContext(linqSerializerOptions, parameters);
9798
ExpressionToSql.Translate(inputExpression, context); // ignore result here
9899

99100
QueryUnderConstruction query = context.currentQuery;
@@ -737,7 +738,7 @@ private static SqlScalarExpression VisitParameter(ParameterExpression inputExpre
737738
private static SqlScalarExpression VisitMemberAccess(MemberExpression inputExpression, TranslationContext context)
738739
{
739740
SqlScalarExpression memberExpression = ExpressionToSql.VisitScalarExpression(inputExpression.Expression, context);
740-
string memberName = inputExpression.Member.GetMemberName(context?.serializationOptions);
741+
string memberName = inputExpression.Member.GetMemberName(context?.linqSerializerOptions);
741742

742743
// if expression is nullable
743744
if (inputExpression.Expression.Type.IsNullable())
@@ -784,7 +785,7 @@ private static SqlScalarExpression[] VisitExpressionList(ReadOnlyCollection<Expr
784785
private static SqlObjectProperty VisitMemberAssignment(MemberAssignment inputExpression, TranslationContext context)
785786
{
786787
SqlScalarExpression assign = ExpressionToSql.VisitScalarExpression(inputExpression.Expression, context);
787-
string memberName = inputExpression.Member.GetMemberName(context?.serializationOptions);
788+
string memberName = inputExpression.Member.GetMemberName(context?.linqSerializerOptions);
788789
SqlPropertyName propName = SqlPropertyName.Create(memberName);
789790
SqlObjectProperty prop = SqlObjectProperty.Create(propName, assign);
790791
return prop;
@@ -826,7 +827,7 @@ private static SqlObjectProperty[] CreateInitializers(ReadOnlyCollection<Express
826827
MemberInfo member = members[i];
827828
SqlScalarExpression value = ExpressionToSql.VisitScalarExpression(arg, context);
828829

829-
string memberName = member.GetMemberName(context?.serializationOptions);
830+
string memberName = member.GetMemberName(context?.linqSerializerOptions);
830831
SqlPropertyName propName = SqlPropertyName.Create(memberName);
831832
SqlObjectProperty prop = SqlObjectProperty.Create(propName, value);
832833
result[i] = prop;

Microsoft.Azure.Cosmos/src/Linq/SQLTranslator.cs

+8-7
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ namespace Microsoft.Azure.Cosmos.Linq
66
using System.Collections.Generic;
77
using System.Linq.Expressions;
88
using Microsoft.Azure.Cosmos.Query.Core;
9+
using Microsoft.Azure.Cosmos.Serializer;
910
using Microsoft.Azure.Cosmos.SqlObjects;
1011

1112
/// <summary>
@@ -17,13 +18,13 @@ internal static class SqlTranslator
1718
/// This function exists for testing only.
1819
/// </summary>
1920
/// <param name="inputExpression">Expression to translate.</param>
20-
/// <param name="serializationOptions">Optional serializer options.</param>
21+
/// <param name="linqSerializerOptions">Optional serializer options.</param>
2122
/// <returns>A string describing the expression translation.</returns>
2223
internal static string TranslateExpression(
2324
Expression inputExpression,
24-
CosmosSerializationOptions serializationOptions = null)
25+
CosmosLinqSerializerOptions linqSerializerOptions = null)
2526
{
26-
TranslationContext context = new TranslationContext(serializationOptions);
27+
TranslationContext context = new TranslationContext(linqSerializerOptions);
2728

2829
inputExpression = ConstantEvaluator.PartialEval(inputExpression);
2930
SqlScalarExpression scalarExpression = ExpressionToSql.VisitNonSubqueryScalarExpression(inputExpression, context);
@@ -32,9 +33,9 @@ internal static string TranslateExpression(
3233

3334
internal static string TranslateExpressionOld(
3435
Expression inputExpression,
35-
CosmosSerializationOptions serializationOptions = null)
36+
CosmosLinqSerializerOptions linqSerializerOptions = null)
3637
{
37-
TranslationContext context = new TranslationContext(serializationOptions);
38+
TranslationContext context = new TranslationContext(linqSerializerOptions);
3839

3940
inputExpression = ConstantFolding.Fold(inputExpression);
4041
SqlScalarExpression scalarExpression = ExpressionToSql.VisitNonSubqueryScalarExpression(inputExpression, context);
@@ -43,11 +44,11 @@ internal static string TranslateExpressionOld(
4344

4445
internal static SqlQuerySpec TranslateQuery(
4546
Expression inputExpression,
46-
CosmosSerializationOptions serializationOptions,
47+
CosmosLinqSerializerOptions linqSerializerOptions,
4748
IDictionary<object, string> parameters)
4849
{
4950
inputExpression = ConstantEvaluator.PartialEval(inputExpression);
50-
SqlQuery query = ExpressionToSql.TranslateQuery(inputExpression, parameters, serializationOptions);
51+
SqlQuery query = ExpressionToSql.TranslateQuery(inputExpression, parameters, linqSerializerOptions);
5152
string queryText = null;
5253
SqlParameterCollection sqlParameters = new SqlParameterCollection();
5354
if (parameters != null && parameters.Count > 0)

Microsoft.Azure.Cosmos/src/Linq/TranslationContext.cs

+4-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ namespace Microsoft.Azure.Cosmos.Linq
77
using System;
88
using System.Collections.Generic;
99
using System.Linq.Expressions;
10+
using Microsoft.Azure.Cosmos.Serializer;
1011
using Microsoft.Azure.Cosmos.SqlObjects;
1112
using static Microsoft.Azure.Cosmos.Linq.ExpressionToSql;
1213
using static Microsoft.Azure.Cosmos.Linq.FromParameterBindings;
@@ -63,14 +64,14 @@ public TranslationContext()
6364
this.subqueryBindingStack = new Stack<SubqueryBinding>();
6465
}
6566

66-
public TranslationContext(CosmosSerializationOptions serializationOptions, IDictionary<object, string> parameters = null)
67+
public TranslationContext(CosmosLinqSerializerOptions linqSerializerOptions, IDictionary<object, string> parameters = null)
6768
: this()
6869
{
69-
this.serializationOptions = serializationOptions;
70+
this.linqSerializerOptions = linqSerializerOptions;
7071
this.parameters = parameters;
7172
}
7273

73-
public CosmosSerializationOptions serializationOptions;
74+
public CosmosLinqSerializerOptions linqSerializerOptions;
7475

7576
public Expression LookupSubstitution(ParameterExpression parameter)
7677
{

Microsoft.Azure.Cosmos/src/Linq/TypeSystem.cs

+4-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ namespace Microsoft.Azure.Cosmos.Linq
1111
using System.Reflection;
1212
using System.Runtime.CompilerServices;
1313
using System.Runtime.Serialization;
14+
using Microsoft.Azure.Cosmos.Serializer;
1415
using Microsoft.Azure.Documents;
1516
using Newtonsoft.Json;
1617

@@ -21,7 +22,7 @@ public static Type GetElementType(Type type)
2122
return GetElementType(type, new HashSet<Type>());
2223
}
2324

24-
public static string GetMemberName(this MemberInfo memberInfo, CosmosSerializationOptions cosmosSerializationOptions = null)
25+
public static string GetMemberName(this MemberInfo memberInfo, CosmosLinqSerializerOptions linqSerializerOptions = null)
2526
{
2627
string memberName = null;
2728
// Json.Net honors JsonPropertyAttribute more than DataMemberAttribute
@@ -49,9 +50,9 @@ public static string GetMemberName(this MemberInfo memberInfo, CosmosSerializati
4950
memberName = memberInfo.Name;
5051
}
5152

52-
if (cosmosSerializationOptions != null)
53+
if (linqSerializerOptions != null)
5354
{
54-
memberName = CosmosSerializationUtil.GetStringWithPropertyNamingPolicy(cosmosSerializationOptions, memberName);
55+
memberName = CosmosSerializationUtil.GetStringWithPropertyNamingPolicy(linqSerializerOptions, memberName);
5556
}
5657

5758
return memberName;

0 commit comments

Comments
 (0)