Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LINQ: Adds camelCase support to GetItemLinqQueryable() as optional parameter #2220

Merged
merged 12 commits into from
Feb 24, 2021
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1032,6 +1032,7 @@ public abstract FeedIterator<T> GetItemQueryIterator<T>(
/// <param name="allowSynchronousQueryExecution">(Optional)the option which allows the query to be executed synchronously via IOrderedQueryable.</param>
/// <param name="continuationToken">(Optional) The continuation token in the Azure Cosmos DB service.</param>
/// <param name="requestOptions">(Optional) The options for the item query request.</param>
/// <param name="cosmosPropertyNamingPolicy">(Optional) To decide whether property names will be read as camelcase in LINQ. This flag overrides the CosmosSerializationOptions.</param>
/// <returns>(Optional) An IOrderedQueryable{T} that can evaluate the query.</returns>
/// <example>
/// 1. This example below shows LINQ query generation and blocked execution.
Expand Down Expand Up @@ -1098,10 +1099,12 @@ public abstract FeedIterator<T> GetItemQueryIterator<T>(
/// <remarks>
/// The Azure Cosmos DB LINQ provider compiles LINQ to SQL statements. Refer to https://docs.microsoft.com/azure/cosmos-db/sql-query-linq-to-sql for the list of expressions supported by the Azure Cosmos DB LINQ provider. ToString() on the generated IQueryable returns the translated SQL statement. The Azure Cosmos DB provider translates JSON.NET and DataContract serialization attributes for members to their JSON property names.
/// </remarks>
/// <seealso cref="CosmosSerializationOptions"/>
public abstract IOrderedQueryable<T> GetItemLinqQueryable<T>(
bool allowSynchronousQueryExecution = false,
string continuationToken = null,
QueryRequestOptions requestOptions = null);
QueryRequestOptions requestOptions = null,
j82w marked this conversation as resolved.
Show resolved Hide resolved
CosmosPropertyNamingPolicy? cosmosPropertyNamingPolicy = null);
j82w marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
/// Delegate to receive the changes within a <see cref="ChangeFeedProcessor"/> execution.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,18 +432,28 @@ public override FeedIterator<T> GetItemQueryIterator<T>(
public override IOrderedQueryable<T> GetItemLinqQueryable<T>(
bool allowSynchronousQueryExecution = false,
string continuationToken = null,
QueryRequestOptions requestOptions = null)
QueryRequestOptions requestOptions = null,
CosmosPropertyNamingPolicy? cosmosPropertyNamingPolicy = null)
{
requestOptions ??= new QueryRequestOptions();

CosmosSerializationOptions serializationOptions = this.ClientContext.ClientOptions.SerializerOptions;
if (cosmosPropertyNamingPolicy.HasValue)
{
serializationOptions = new CosmosSerializationOptions
{
PropertyNamingPolicy = cosmosPropertyNamingPolicy.Value
j82w marked this conversation as resolved.
Show resolved Hide resolved
};
}

return new CosmosLinqQuery<T>(
this,
this.ClientContext.ResponseFactory,
(CosmosQueryClientCore)this.queryClient,
continuationToken,
requestOptions,
allowSynchronousQueryExecution,
this.ClientContext.ClientOptions.SerializerOptions);
serializationOptions);
}

public override FeedIterator<T> GetItemQueryIterator<T>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,12 +351,14 @@ public override FeedIterator<T> GetItemQueryIterator<T>(

public override IOrderedQueryable<T> GetItemLinqQueryable<T>(bool allowSynchronousQueryExecution = false,
string continuationToken = null,
QueryRequestOptions requestOptions = null)
QueryRequestOptions requestOptions = null,
CosmosPropertyNamingPolicy? cosmosPropertyNamingPolicy = null)
{
return base.GetItemLinqQueryable<T>(
allowSynchronousQueryExecution,
continuationToken,
requestOptions);
requestOptions,
cosmosPropertyNamingPolicy);
}

public override ChangeFeedProcessorBuilder GetChangeFeedProcessorBuilder<T>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,43 @@ public async Task ItemLINQWithCamelCaseSerializerOptions(bool isGatewayMode)
Assert.AreEqual(queriable.Count(), 2);
}

[TestMethod]
public async Task LINQWithCamelCaseFlagTest()
{
static void builder(CosmosClientBuilder action)
{
action.WithSerializerOptions(new CosmosSerializationOptions()
{
PropertyNamingPolicy = CosmosPropertyNamingPolicy.CamelCase
});
}
CosmosClient camelCaseCosmosClient = TestCommon.CreateCosmosClient(builder, false);
Cosmos.Database database = camelCaseCosmosClient.GetDatabase(this.database.Id);
Container containerFromCamelCaseClient = database.GetContainer(this.Container.Id);

IList<ToDoActivity> itemList = await ToDoActivity.CreateRandomItems(containerFromCamelCaseClient, pkCount: 2, perPKItemCount: 1, randomPartitionKey: true);

// NamingPolicy - CamelCase set
IOrderedQueryable<ToDoActivity> linqQueryable = this.Container.GetItemLinqQueryable<ToDoActivity>(true, null, null, CosmosPropertyNamingPolicy.CamelCase);
IQueryable<ToDoActivity> queriable = linqQueryable.Where(item => item.CamelCase == "camelCase");
Assert.AreEqual(queriable.Count(), 2);

// Override camelcase client with default
linqQueryable = containerFromCamelCaseClient.GetItemLinqQueryable<ToDoActivity>(true, null, null, CosmosPropertyNamingPolicy.Default);
queriable = linqQueryable.Where(item => item.CamelCase == "camelCase");
asketagarwal marked this conversation as resolved.
Show resolved Hide resolved
Assert.AreEqual(queriable.Count(), 0);

// Normal client - CamelCase flag not set
linqQueryable = this.Container.GetItemLinqQueryable<ToDoActivity>(true);
queriable = linqQueryable.Where(item => item.CamelCase == "camelCase");
Assert.AreEqual(queriable.Count(), 0);

// Camel case client - CamelCase flag not set
linqQueryable = containerFromCamelCaseClient.GetItemLinqQueryable<ToDoActivity>(true);
queriable = linqQueryable.Where(item => item.CamelCase == "camelCase");
Assert.AreEqual(queriable.Count(), 2);
}

[TestMethod]
public async Task LinqParameterisedTest1()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -815,10 +815,10 @@
"Attributes": [],
"MethodInfo": "Microsoft.Azure.Cosmos.TransactionalBatch CreateTransactionalBatch(Microsoft.Azure.Cosmos.PartitionKey);IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
},
"System.Linq.IOrderedQueryable`1[T] GetItemLinqQueryable[T](Boolean, System.String, Microsoft.Azure.Cosmos.QueryRequestOptions)": {
"System.Linq.IOrderedQueryable`1[T] GetItemLinqQueryable[T](Boolean, System.String, Microsoft.Azure.Cosmos.QueryRequestOptions, System.Nullable`1[Microsoft.Azure.Cosmos.CosmosPropertyNamingPolicy])": {
"Type": "Method",
"Attributes": [],
"MethodInfo": "System.Linq.IOrderedQueryable`1[T] GetItemLinqQueryable[T](Boolean, System.String, Microsoft.Azure.Cosmos.QueryRequestOptions);IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:True;IsConstructor:False;IsFinal:False;"
"MethodInfo": "System.Linq.IOrderedQueryable`1[T] GetItemLinqQueryable[T](Boolean, System.String, Microsoft.Azure.Cosmos.QueryRequestOptions, System.Nullable`1[Microsoft.Azure.Cosmos.CosmosPropertyNamingPolicy]);IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:True;IsConstructor:False;IsFinal:False;"
},
"System.String get_Id()": {
"Type": "Method",
Expand Down