Skip to content

Commit 06550af

Browse files
committed
init
1 parent 6eb976b commit 06550af

6 files changed

Lines changed: 95 additions & 43 deletions

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ namespace Microsoft.Azure.Cosmos.Linq
55
{
66
using System;
77
using System.Collections.Generic;
8+
using System.Linq;
89
using System.Linq.Expressions;
910
using System.Reflection;
1011

@@ -40,7 +41,9 @@ public override Expression Visit(Expression expression)
4041

4142
protected override Expression VisitMemberInit(MemberInitExpression node)
4243
{
43-
return node;
44+
return Expression.MemberInit(
45+
node.NewExpression,
46+
node.Bindings.Select(binding => this.VisitMemberBinding(binding)));
4447
}
4548

4649
private Expression EvaluateMemberAccess(Expression expression)

Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationWithCustomSerializerBaseline.TestMemberInitializerDotNetCustomSerializer.xml

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ WHERE (root["NumberValueDotNet"] = 1)]]></SqlQuery>
2828
<SqlQuery><![CDATA[
2929
SELECT VALUE root
3030
FROM root
31-
WHERE (root = {"NumberValueDotNet": 1, "StringValueDotNet": "1", "id": null, "Pk": null, "DateTimeFieldDotNet": null, "DataTypeField": null})]]></SqlQuery>
31+
WHERE (root = {"NumberValueDotNet": 1, "StringValueDotNet": "1", "id": null, "Pk": null, "DateTimeFieldDotNet": null, "DataTypeField": null, "NestedObjects": null})]]></SqlQuery>
3232
<InputData><![CDATA[[
3333
"{\"NumberValueDotNet\": 0, \"StringValueDotNet\": \"0\", \"id\": \"0-False\", \"Pk\": \"Test\"}",
3434
"{\"NumberValueDotNet\": 1, \"StringValueDotNet\": \"1\", \"id\": \"1-False\", \"Pk\": \"Test\"}",
@@ -44,7 +44,7 @@ WHERE (root = {"NumberValueDotNet": 1, "StringValueDotNet": "1", "id": null, "Pk
4444
</Input>
4545
<Output>
4646
<SqlQuery><![CDATA[
47-
SELECT VALUE {"NumberValueDotNet": 1, "StringValueDotNet": "1", "id": null, "Pk": null, "DateTimeFieldDotNet": null, "DataTypeField": null}
47+
SELECT VALUE {"NumberValueDotNet": 1, "StringValueDotNet": "1", "id": null, "Pk": null, "DateTimeFieldDotNet": null, "DataTypeField": null, "NestedObjects": null}
4848
FROM root]]></SqlQuery>
4949
<InputData><![CDATA[[
5050
"{\"NumberValueDotNet\": 0, \"StringValueDotNet\": \"0\", \"id\": \"0-False\", \"Pk\": \"Test\"}",
@@ -65,7 +65,7 @@ FROM root]]></SqlQuery>
6565
</Input>
6666
<Output>
6767
<SqlQuery><![CDATA[
68-
SELECT VALUE ((root["NumberValueDotNet"] > 1) ? {"NumberValueDotNet": 1, "StringValueDotNet": "1", "id": null, "Pk": null, "DateTimeFieldDotNet": null, "DataTypeField": null} : {"NumberValueDotNet": 1, "StringValueDotNet": "1", "id": null, "Pk": null, "DateTimeFieldDotNet": null, "DataTypeField": null})
68+
SELECT VALUE ((root["NumberValueDotNet"] > 1) ? {"NumberValueDotNet": 1, "StringValueDotNet": "1", "id": null, "Pk": null, "DateTimeFieldDotNet": null, "DataTypeField": null, "NestedObjects": null} : {"NumberValueDotNet": 1, "StringValueDotNet": "1", "id": null, "Pk": null, "DateTimeFieldDotNet": null, "DataTypeField": null, "NestedObjects": null})
6969
FROM root]]></SqlQuery>
7070
<InputData><![CDATA[[
7171
"{\"NumberValueDotNet\": 0, \"StringValueDotNet\": \"0\", \"id\": \"0-False\", \"Pk\": \"Test\"}",
@@ -231,6 +231,34 @@ WHERE (root["StringValueDotNet"] != null)]]></SqlQuery>
231231
"{NumericField:0,StringField:0,id:0-False,Pk:Test}",
232232
"{NumericField:1,StringField:1,id:1-False,Pk:Test}",
233233
"{NumericField:2,StringField:2,id:2-False,Pk:Test}"
234+
]]]></Results>
235+
</Output>
236+
</Result>
237+
<Result>
238+
<Input>
239+
<Description><![CDATA[Nested filter]]></Description>
240+
<Expression><![CDATA[query.Select(doc => new DataObjectDotNet() {NestedObjects = doc.NestedObjects.Where(c => (c.id == DisplayClass.searchField)).ToList()})]]></Expression>
241+
</Input>
242+
<Output>
243+
<SqlQuery><![CDATA[
244+
SELECT VALUE {"NestedObjects": v0}
245+
FROM root
246+
JOIN (
247+
SELECT VALUE ARRAY(
248+
SELECT VALUE c0
249+
FROM root
250+
JOIN c0 IN root["NestedObjects"]
251+
WHERE (c0["id"] = "test"))) AS v0
252+
]]></SqlQuery>
253+
<InputData><![CDATA[[
254+
"{\"NumberValueDotNet\": 0, \"StringValueDotNet\": \"0\", \"id\": \"0-False\", \"Pk\": \"Test\"}",
255+
"{\"NumberValueDotNet\": 1, \"StringValueDotNet\": \"1\", \"id\": \"1-False\", \"Pk\": \"Test\"}",
256+
"{\"NumberValueDotNet\": 2, \"StringValueDotNet\": \"2\", \"id\": \"2-False\", \"Pk\": \"Test\"}"
257+
]]]></InputData>
258+
<Results><![CDATA[[
259+
"{NumericField:0,StringField:,id:,Pk:}",
260+
"{NumericField:0,StringField:,id:,Pk:}",
261+
"{NumericField:0,StringField:,id:,Pk:}"
234262
]]]></Results>
235263
</Output>
236264
</Result>

Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationWithCustomSerializerBaseline.TestMemberInitializerDotNetDefaultSerializer.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ WHERE (root["NumberValueDotNet"] = 1)]]></SqlQuery>
2828
<SqlQuery><![CDATA[
2929
SELECT VALUE root
3030
FROM root
31-
WHERE (root = {"NumberValueDotNet": 1, "StringValueDotNet": "1", "id": null, "Pk": null, "DateTimeFieldDotNet": null, "DataTypeField": null})]]></SqlQuery>
31+
WHERE (root = {"NumberValueDotNet": 1, "StringValueDotNet": "1", "id": null, "Pk": null, "DateTimeFieldDotNet": null, "DataTypeField": null, "NestedObjects": null})]]></SqlQuery>
3232
<InputData><![CDATA[[
3333
"{\"NumberValueDotNet\": 0, \"StringValueDotNet\": \"0\", \"id\": \"0-False\", \"Pk\": \"Test\"}",
3434
"{\"NumberValueDotNet\": 1, \"StringValueDotNet\": \"1\", \"id\": \"1-False\", \"Pk\": \"Test\"}",
@@ -44,7 +44,7 @@ WHERE (root = {"NumberValueDotNet": 1, "StringValueDotNet": "1", "id": null, "Pk
4444
</Input>
4545
<Output>
4646
<SqlQuery><![CDATA[
47-
SELECT VALUE {"NumberValueDotNet": 1, "StringValueDotNet": "1", "id": null, "Pk": null, "DateTimeFieldDotNet": null, "DataTypeField": null}
47+
SELECT VALUE {"NumberValueDotNet": 1, "StringValueDotNet": "1", "id": null, "Pk": null, "DateTimeFieldDotNet": null, "DataTypeField": null, "NestedObjects": null}
4848
FROM root]]></SqlQuery>
4949
<InputData><![CDATA[[
5050
"{\"NumberValueDotNet\": 0, \"StringValueDotNet\": \"0\", \"id\": \"0-False\", \"Pk\": \"Test\"}",
@@ -65,7 +65,7 @@ FROM root]]></SqlQuery>
6565
</Input>
6666
<Output>
6767
<SqlQuery><![CDATA[
68-
SELECT VALUE ((root["NumberValueDotNet"] > 1) ? {"NumberValueDotNet": 1, "StringValueDotNet": "1", "id": null, "Pk": null, "DateTimeFieldDotNet": null, "DataTypeField": null} : {"NumberValueDotNet": 1, "StringValueDotNet": "1", "id": null, "Pk": null, "DateTimeFieldDotNet": null, "DataTypeField": null})
68+
SELECT VALUE ((root["NumberValueDotNet"] > 1) ? {"NumberValueDotNet": 1, "StringValueDotNet": "1", "id": null, "Pk": null, "DateTimeFieldDotNet": null, "DataTypeField": null, "NestedObjects": null} : {"NumberValueDotNet": 1, "StringValueDotNet": "1", "id": null, "Pk": null, "DateTimeFieldDotNet": null, "DataTypeField": null, "NestedObjects": null})
6969
FROM root]]></SqlQuery>
7070
<InputData><![CDATA[[
7171
"{\"NumberValueDotNet\": 0, \"StringValueDotNet\": \"0\", \"id\": \"0-False\", \"Pk\": \"Test\"}",

Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemLinqTests.cs

Lines changed: 46 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@
44

55
namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests
66
{
7-
using Microsoft.Azure.Cosmos.Fluent;
8-
using Microsoft.Azure.Cosmos.Linq;
9-
using Microsoft.VisualStudio.TestTools.UnitTesting;
10-
using Newtonsoft.Json;
117
using System;
128
using System.Collections.Generic;
139
using System.Collections.ObjectModel;
1410
using System.Linq;
1511
using System.Linq.Dynamic;
1612
using System.Linq.Expressions;
1713
using System.Threading.Tasks;
14+
using Microsoft.Azure.Cosmos.Fluent;
15+
using Microsoft.Azure.Cosmos.Linq;
16+
using Microsoft.VisualStudio.TestTools.UnitTesting;
17+
using Newtonsoft.Json;
1818

1919
[TestClass]
2020
public class CosmosItemLinqTests : BaseCosmosClientHelper
@@ -321,64 +321,64 @@ public async Task QueryableExtentionFunctionsTest()
321321
Assert.AreEqual(10, count);
322322

323323
Response<int> intSum = await linqQueryable.Select(item => item.taskNum).SumAsync();
324-
this.VerifyResponse(intSum, 420, queryRequestOptions);
324+
this.VerifyResponse(intSum, 420);
325325

326326
Response<int?> intNullableSum = await linqQueryable.Select(item => (int?)item.taskNum).SumAsync();
327-
this.VerifyResponse(intNullableSum, 420, queryRequestOptions);
327+
this.VerifyResponse(intNullableSum, 420);
328328

329329
Response<float> floatSum = await linqQueryable.Select(item => (float)item.taskNum).SumAsync();
330-
this.VerifyResponse(floatSum, 420, queryRequestOptions);
330+
this.VerifyResponse(floatSum, 420);
331331

332332
Response<float?> floatNullableSum = await linqQueryable.Select(item => (float?)item.taskNum).SumAsync();
333-
this.VerifyResponse(floatNullableSum, 420, queryRequestOptions);
333+
this.VerifyResponse(floatNullableSum, 420);
334334

335335
Response<double> doubleSum = await linqQueryable.Select(item => (double)item.taskNum).SumAsync();
336-
this.VerifyResponse(doubleSum, 420, queryRequestOptions);
336+
this.VerifyResponse(doubleSum, 420);
337337

338338
Response<double?> doubleNullableSum = await linqQueryable.Select(item => (double?)item.taskNum).SumAsync();
339-
this.VerifyResponse(doubleNullableSum, 420, queryRequestOptions);
339+
this.VerifyResponse(doubleNullableSum, 420);
340340

341341
Response<long> longSum = await linqQueryable.Select(item => (long)item.taskNum).SumAsync();
342-
this.VerifyResponse(longSum, 420, queryRequestOptions);
342+
this.VerifyResponse(longSum, 420);
343343

344344
Response<long?> longNullableSum = await linqQueryable.Select(item => (long?)item.taskNum).SumAsync();
345-
this.VerifyResponse(longNullableSum, 420, queryRequestOptions);
345+
this.VerifyResponse(longNullableSum, 420);
346346

347347
Response<decimal> decimalSum = await linqQueryable.Select(item => (decimal)item.taskNum).SumAsync();
348-
this.VerifyResponse(decimalSum, 420, queryRequestOptions);
348+
this.VerifyResponse(decimalSum, 420);
349349

350350
Response<decimal?> decimalNullableSum = await linqQueryable.Select(item => (decimal?)item.taskNum).SumAsync();
351-
this.VerifyResponse(decimalNullableSum, 420, queryRequestOptions);
351+
this.VerifyResponse(decimalNullableSum, 420);
352352

353353
Response<double> intToDoubleAvg = await linqQueryable.Select(item => item.taskNum).AverageAsync();
354-
this.VerifyResponse(intToDoubleAvg, 42, queryRequestOptions);
354+
this.VerifyResponse(intToDoubleAvg, 42);
355355

356356
Response<double?> intToDoubleNulableAvg = await linqQueryable.Select(item => (double?)item.taskNum).AverageAsync();
357-
this.VerifyResponse(intToDoubleNulableAvg, 42, queryRequestOptions);
357+
this.VerifyResponse(intToDoubleNulableAvg, 42);
358358

359359
Response<float> floatAvg = await linqQueryable.Select(item => (float)item.taskNum).AverageAsync();
360-
this.VerifyResponse(floatAvg, 42, queryRequestOptions);
360+
this.VerifyResponse(floatAvg, 42);
361361

362362
Response<float?> floatNullableAvg = await linqQueryable.Select(item => (float?)item.taskNum).AverageAsync();
363-
this.VerifyResponse(floatNullableAvg, 42, queryRequestOptions);
363+
this.VerifyResponse(floatNullableAvg, 42);
364364

365365
Response<double> doubleAvg = await linqQueryable.Select(item => (double)item.taskNum).AverageAsync();
366-
this.VerifyResponse(doubleAvg, 42, queryRequestOptions);
366+
this.VerifyResponse(doubleAvg, 42);
367367

368368
Response<double?> doubleNullableAvg = await linqQueryable.Select(item => (double?)item.taskNum).AverageAsync();
369-
this.VerifyResponse(doubleNullableAvg, 42, queryRequestOptions);
369+
this.VerifyResponse(doubleNullableAvg, 42);
370370

371371
Response<double> longToDoubleAvg = await linqQueryable.Select(item => (long)item.taskNum).AverageAsync();
372-
this.VerifyResponse(longToDoubleAvg, 42, queryRequestOptions);
372+
this.VerifyResponse(longToDoubleAvg, 42);
373373

374374
Response<double?> longToNullableDoubleAvg = await linqQueryable.Select(item => (long?)item.taskNum).AverageAsync();
375-
this.VerifyResponse(longToNullableDoubleAvg, 42, queryRequestOptions);
375+
this.VerifyResponse(longToNullableDoubleAvg, 42);
376376

377377
Response<decimal> decimalAvg = await linqQueryable.Select(item => (decimal)item.taskNum).AverageAsync();
378-
this.VerifyResponse(decimalAvg, 42, queryRequestOptions);
378+
this.VerifyResponse(decimalAvg, 42);
379379

380380
Response<decimal?> decimalNullableAvg = await linqQueryable.Select(item => (decimal?)item.taskNum).AverageAsync();
381-
this.VerifyResponse(decimalNullableAvg, 42, queryRequestOptions);
381+
this.VerifyResponse(decimalNullableAvg, 42);
382382

383383
//Adding more items to test min and max function
384384
ToDoActivity toDoActivity = ToDoActivity.CreateRandomToDoActivity();
@@ -969,6 +969,27 @@ public async Task LinqSkipOrderBy()
969969
Assert.AreEqual(2, count);
970970
}
971971

972+
[TestMethod]
973+
public async Task LinqMemberIndexing()
974+
{
975+
string testString = "Test";
976+
977+
IList<ToDoActivity> itemList = await ToDoActivity.CreateRandomItems(this.Container, 3, randomPartitionKey: true);
978+
IQueryable<ToDoActivity> queryable = this.Container.GetItemLinqQueryable<ToDoActivity>()
979+
.Select(q => new ToDoActivity { id = q.childrenMap[testString].id });
980+
981+
FeedIterator<ToDoActivity> feedIterator = queryable.ToFeedIterator();
982+
983+
int count = 0;
984+
while (feedIterator.HasMoreResults)
985+
{
986+
FeedResponse<ToDoActivity> feedResponse = feedIterator.ReadNextAsync().Result;
987+
count += feedResponse.Count;
988+
}
989+
990+
Assert.AreEqual(3, count);
991+
}
992+
972993
private class NumberLinqItem
973994
{
974995
public string id;
@@ -1005,10 +1026,7 @@ private async Task<List<T>> FetchResults<T>(QueryDefinition queryDefinition)
10051026
return itemList;
10061027
}
10071028

1008-
private void VerifyResponse<T>(
1009-
Response<T> response,
1010-
T expectedValue,
1011-
QueryRequestOptions queryRequestOptions)
1029+
private void VerifyResponse<T>(Response<T> response, T expectedValue)
10121030
{
10131031
Assert.AreEqual<T>(expectedValue, response.Resource);
10141032
Assert.IsTrue(response.RequestCharge > 0);

Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTranslationWithCustomSerializerBaseline.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ public class LinqTranslationWithCustomSerializerBaseline : BaselineTests<LinqTes
3737
private static Container TestSTJContainer;
3838

3939
private const int RecordCount = 3;
40-
private const int MaxValue = 500;
41-
private const int MaxStringLength = 100;
4240
private const int PropertyCount = 4;
4341

4442
[ClassInitialize]
@@ -113,6 +111,7 @@ public void TestMemberInitializerDotNetCustomSerializer()
113111
(_, getQuery) = this.InsertDataAndGetQueryables<DataObjectDotNet>(true, TestLinqContainer);
114112

115113
string insertedData = this.GetInsertedData(TestLinqContainer).Result;
114+
string searchField = "test";
116115

117116
List<LinqTestInput> inputs = new List<LinqTestInput>
118117
{
@@ -128,6 +127,7 @@ public void TestMemberInitializerDotNetCustomSerializer()
128127
new LinqTestInput("Filter w/ non-null nullable property", b => getQuery(b).Where(doc => doc.DateTimeField == new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)), skipVerification : true, inputData: insertedData),
129128
new LinqTestInput("Filter w/ non-null nullable enum", b => getQuery(b).Where(doc => doc.DataTypeField == DataType.Point), skipVerification : true, inputData: insertedData),
130129
new LinqTestInput("Filter w/ string null comparison", b => getQuery(b).Where(doc => doc.StringField != null), skipVerification : true, inputData: insertedData),
130+
new LinqTestInput("Nested filter", b => getQuery(b).Select(doc => new DataObjectDotNet { NestedObjects = doc.NestedObjects.Where(c => c.id == searchField).ToList()}), skipVerification : true, inputData: insertedData)
131131
};
132132

133133
this.ExecuteTestSuite(inputs);
@@ -401,6 +401,8 @@ private class DataObjectDotNet : LinqTestObject
401401
[System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Serialization.JsonStringEnumConverter))]
402402
public DataType? DataTypeField { get; set; }
403403

404+
public List<DataObjectDotNet> NestedObjects { get; set; }
405+
404406
public DataObjectDotNet() { }
405407

406408
public DataObjectDotNet(double numericField, string stringField, string id, string pk)

Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Utils/ToDoActivity.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
//------------------------------------------------------------
22
// Copyright (c) Microsoft Corporation. All rights reserved.
33
//------------------------------------------------------------
4-
5-
using Microsoft.VisualStudio.TestTools.UnitTesting;
6-
using System;
7-
using System.Collections.Generic;
8-
using System.Threading.Tasks;
9-
104
namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests
115
{
6+
using Microsoft.VisualStudio.TestTools.UnitTesting;
7+
using System;
8+
using System.Collections.Generic;
9+
using System.Threading.Tasks;
10+
1211
public class ToDoActivity
1312
{
1413
public string id { get; set; }
@@ -23,6 +22,8 @@ public class ToDoActivity
2322

2423
public ToDoActivity[] children { get; set; }
2524

25+
public Dictionary<string, ToDoActivity> childrenMap { get; set; }
26+
2627
public override bool Equals(Object obj)
2728
{
2829
ToDoActivity input = obj as ToDoActivity;

0 commit comments

Comments
 (0)