Skip to content

Commit af9e1dc

Browse files
committed
Add complex collection support to PropertyValues
Part of #31237
1 parent c3a82bd commit af9e1dc

File tree

44 files changed

+3355
-360
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+3355
-360
lines changed

src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ static void ValidateType(ITypeBase typeBase, IDiagnosticsLogger<DbLoggerCategory
8383

8484
foreach (var complexProperty in typeBase.GetDeclaredComplexProperties())
8585
{
86+
if (complexProperty.IsCollection)
87+
{
88+
throw new InvalidOperationException(
89+
CosmosStrings.ComplexTypeCollectionsNotSupported(
90+
complexProperty.ComplexType.ShortName(),
91+
complexProperty.Name));
92+
}
93+
8694
ValidateType(complexProperty.ComplexType, logger);
8795
}
8896
}

src/EFCore.Cosmos/Properties/CosmosStrings.Designer.cs

Lines changed: 34 additions & 20 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/EFCore.Cosmos/Properties/CosmosStrings.resx

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<root>
3-
<!--
4-
Microsoft ResX Schema
5-
3+
<!--
4+
Microsoft ResX Schema
5+
66
Version 2.0
7-
8-
The primary goals of this format is to allow a simple XML format
9-
that is mostly human readable. The generation and parsing of the
10-
various data types are done through the TypeConverter classes
7+
8+
The primary goals of this format is to allow a simple XML format
9+
that is mostly human readable. The generation and parsing of the
10+
various data types are done through the TypeConverter classes
1111
associated with the data types.
12-
12+
1313
Example:
14-
14+
1515
... ado.net/XML headers & schema ...
1616
<resheader name="resmimetype">text/microsoft-resx</resheader>
1717
<resheader name="version">2.0</resheader>
@@ -26,36 +26,36 @@
2626
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
2727
<comment>This is a comment</comment>
2828
</data>
29-
30-
There are any number of "resheader" rows that contain simple
29+
30+
There are any number of "resheader" rows that contain simple
3131
name/value pairs.
32-
33-
Each data row contains a name, and value. The row also contains a
34-
type or mimetype. Type corresponds to a .NET class that support
35-
text/value conversion through the TypeConverter architecture.
36-
Classes that don't support this are serialized and stored with the
32+
33+
Each data row contains a name, and value. The row also contains a
34+
type or mimetype. Type corresponds to a .NET class that support
35+
text/value conversion through the TypeConverter architecture.
36+
Classes that don't support this are serialized and stored with the
3737
mimetype set.
38-
39-
The mimetype is used for serialized objects, and tells the
40-
ResXResourceReader how to depersist the object. This is currently not
38+
39+
The mimetype is used for serialized objects, and tells the
40+
ResXResourceReader how to depersist the object. This is currently not
4141
extensible. For a given mimetype the value must be set accordingly:
42-
43-
Note - application/x-microsoft.net.object.binary.base64 is the format
44-
that the ResXResourceWriter will generate, however the reader can
42+
43+
Note - application/x-microsoft.net.object.binary.base64 is the format
44+
that the ResXResourceWriter will generate, however the reader can
4545
read any of the formats listed below.
46-
46+
4747
mimetype: application/x-microsoft.net.object.binary.base64
48-
value : The object must be serialized with
48+
value : The object must be serialized with
4949
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
5050
: and then encoded with base64 encoding.
51-
51+
5252
mimetype: application/x-microsoft.net.object.soap.base64
53-
value : The object must be serialized with
53+
value : The object must be serialized with
5454
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
5555
: and then encoded with base64 encoding.
5656
5757
mimetype: application/x-microsoft.net.object.bytearray.base64
58-
value : The object must be serialized into a byte array
58+
value : The object must be serialized into a byte array
5959
: using a System.ComponentModel.TypeConverter
6060
: and then encoded with base64 encoding.
6161
-->
@@ -132,6 +132,9 @@
132132
<data name="ComplexProjectionInSubqueryNotSupported" xml:space="preserve">
133133
<value>Complex projections in subqueries are currently unsupported.</value>
134134
</data>
135+
<data name="ComplexTypeCollectionsNotSupported" xml:space="preserve">
136+
<value>Complex type collections are currently not supported in Cosmos. Consider using owned type collections. Complex type: '{complexType}', property: '{property}'. See https://github.com/dotnet/efcore/issues/31253 for more details.</value>
137+
</data>
135138
<data name="CompositeFullTextIndex" xml:space="preserve">
136139
<value>A full-text index on '{entityType}' is defined over multiple properties (`{properties}`). A full-text index can only target a single property.</value>
137140
</data>
@@ -322,15 +325,15 @@
322325
<data name="PartitionKeyBadValueType" xml:space="preserve">
323326
<value>The partition key value supplied for '{propertyType}' property '{entityType}.{property}' is of type '{valueType}'. Partition key values must be of a type assignable to the property.</value>
324327
</data>
325-
<data name="PartitionKeyNotOnRoot" xml:space="preserve">
326-
<value>A partition key is defined on entity type '{entityType}', which inherits from '{baseEntityType}'. Partition keys must be defined on the root entity type of a hierarchy.</value>
327-
</data>
328328
<data name="PartitionKeyMissing" xml:space="preserve">
329329
<value>Unable to execute a 'ReadItem' query since the partition key value is missing. Consider using the 'WithPartitionKey' method on the query to specify partition key to use.</value>
330330
</data>
331331
<data name="PartitionKeyMissingProperty" xml:space="preserve">
332332
<value>The partition key for entity type '{entityType}' is set to '{property}', but there is no property with that name.</value>
333333
</data>
334+
<data name="PartitionKeyNotOnRoot" xml:space="preserve">
335+
<value>A partition key is defined on entity type '{entityType}', which inherits from '{baseEntityType}'. Partition keys must be defined on the root entity type of a hierarchy.</value>
336+
</data>
334337
<data name="PartitionKeyStoreNameMismatch" xml:space="preserve">
335338
<value>The partition key property '{property1}' on '{entityType1}' is mapped as '{storeName1}', but the partition key property '{property2}' on '{entityType2}' is mapped as '{storeName2}'. All partition key properties need to be mapped to the same store property for entity types mapped to the same container.</value>
336339
</data>

src/EFCore.InMemory/Storage/Internal/InMemoryTable.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public InMemoryTable(
4444
_sensitiveLoggingEnabled = sensitiveLoggingEnabled;
4545
_nullabilityCheckEnabled = nullabilityCheckEnabled;
4646
_rows = new Dictionary<TKey, object?[]>(_keyValueFactory.EqualityComparer);
47-
var properties = entityType.GetFlattenedProperties().ToList();
47+
var properties = entityType.GetFlattenedProperties().AsList();
4848
_propertyCount = properties.Count;
4949

5050
foreach (var property in properties)
@@ -163,7 +163,7 @@ private static List<ValueComparer> GetKeyComparers(IEnumerable<IProperty> proper
163163
/// </summary>
164164
public virtual void Create(IUpdateEntry entry, IDiagnosticsLogger<DbLoggerCategory.Update> updateLogger)
165165
{
166-
var properties = entry.EntityType.GetFlattenedProperties().ToList();
166+
var properties = entry.EntityType.GetFlattenedProperties().AsList();
167167
var row = new object?[properties.Count];
168168
var nullabilityErrors = new List<IProperty>();
169169

@@ -197,7 +197,7 @@ public virtual void Delete(IUpdateEntry entry, IDiagnosticsLogger<DbLoggerCatego
197197

198198
if (_rows.TryGetValue(key, out var row))
199199
{
200-
var properties = entry.EntityType.GetFlattenedProperties().ToList();
200+
var properties = entry.EntityType.GetFlattenedProperties().AsList();
201201
var concurrencyConflicts = new Dictionary<IProperty, object?>();
202202

203203
for (var index = 0; index < properties.Count; index++)
@@ -269,7 +269,7 @@ public virtual void Update(IUpdateEntry entry, IDiagnosticsLogger<DbLoggerCatego
269269

270270
if (_rows.TryGetValue(key, out var row))
271271
{
272-
var properties = entry.EntityType.GetFlattenedProperties().ToList();
272+
var properties = entry.EntityType.GetFlattenedProperties().AsList();
273273
var comparers = GetKeyComparers(properties);
274274
var valueBuffer = new object?[properties.Count];
275275
var concurrencyConflicts = new Dictionary<IProperty, object?>();

0 commit comments

Comments
 (0)