Skip to content

Commit

Permalink
Rename the 'id' property created by convention to '__id' to avoid it …
Browse files Browse the repository at this point in the history
…clashing with an entity property.

Make sure that the property created by the convention is removed if any other property is mapped to id (the new property should get the value generator).
Validate all properties have distinct database names
Remove the value generator from the property mapped to id if it's part of the PK
Escape | using ^ instead of /

Fixes #17751
Fixes #20665
  • Loading branch information
AndriySvyryd committed Jun 15, 2020
1 parent 8a62dac commit bff18de
Show file tree
Hide file tree
Showing 15 changed files with 354 additions and 98 deletions.
56 changes: 55 additions & 1 deletion src/EFCore.Cosmos/Internal/CosmosModelValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public override void Validate(IModel model, IDiagnosticsLogger<DbLoggerCategory.
{
base.Validate(model, logger);

ValidateDatabaseProperties(model, logger);
ValidateKeys(model, logger);
ValidateSharedContainerCompatibility(model, logger);
ValidateOnlyETagConcurrencyToken(model, logger);
Expand Down Expand Up @@ -219,7 +220,7 @@ protected virtual void ValidateKeys(
continue;
}

var idProperty = entityType.GetProperties().FirstOrDefault(p => p.GetJsonPropertyName() == StoreKeyConvention.IdPropertyName);
var idProperty = entityType.GetProperties().FirstOrDefault(p => p.GetJsonPropertyName() == StoreKeyConvention.IdPropertyJsonName);
if (idProperty == null)
{
throw new InvalidOperationException(CosmosStrings.NoIdProperty(entityType.DisplayName()));
Expand Down Expand Up @@ -266,5 +267,58 @@ protected virtual void ValidateKeys(
}
}
}

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
protected virtual void ValidateDatabaseProperties(
[NotNull] IModel model,
[NotNull] IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
{
foreach (var entityType in model.GetEntityTypes())
{
var properties = new Dictionary<string, IPropertyBase>();
foreach (var property in entityType.GetProperties())
{
var jsonName = property.GetJsonPropertyName();
if (string.IsNullOrWhiteSpace(jsonName))
{
continue;
}

if (properties.TryGetValue(jsonName, out var otherProperty))
{
throw new InvalidOperationException(
CosmosStrings.JsonPropertyCollision(property.Name, otherProperty.Name, entityType.DisplayName(), jsonName));
}
else
{
properties[jsonName] = property;
}
}

foreach (var navigation in entityType.GetNavigations())
{
if (!navigation.IsEmbedded())
{
continue;
}

var jsonName = navigation.TargetEntityType.GetContainingPropertyName();
if (properties.TryGetValue(jsonName, out var otherProperty))
{
throw new InvalidOperationException(
CosmosStrings.JsonPropertyCollision(navigation.Name, otherProperty.Name, entityType.DisplayName(), jsonName));
}
else
{
properties[jsonName] = navigation;
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,11 @@ public override ConventionSet CreateConventionSet()
ReplaceConvention(conventionSet.EntityTypeBaseTypeChangedConventions, (DiscriminatorConvention)discriminatorConvention);
ReplaceConvention(conventionSet.EntityTypeBaseTypeChangedConventions, (KeyDiscoveryConvention)keyDiscoveryConvention);

ReplaceConvention(conventionSet.PropertyAddedConventions, (KeyDiscoveryConvention)keyDiscoveryConvention);
conventionSet.EntityTypePrimaryKeyChangedConventions.Add(storeKeyConvention);

conventionSet.KeyAddedConventions.Add(storeKeyConvention);

conventionSet.KeyRemovedConventions.Add(storeKeyConvention);
ReplaceConvention(conventionSet.KeyRemovedConventions, (KeyDiscoveryConvention)keyDiscoveryConvention);

ReplaceConvention(conventionSet.ForeignKeyAddedConventions, (KeyDiscoveryConvention)keyDiscoveryConvention);
Expand All @@ -75,6 +78,10 @@ public override ConventionSet CreateConventionSet()
conventionSet.EntityTypeAnnotationChangedConventions.Add(storeKeyConvention);
conventionSet.EntityTypeAnnotationChangedConventions.Add(keyDiscoveryConvention);

ReplaceConvention(conventionSet.PropertyAddedConventions, (KeyDiscoveryConvention)keyDiscoveryConvention);

conventionSet.PropertyAnnotationChangedConventions.Add(storeKeyConvention);

return conventionSet;
}
}
Expand Down
Loading

0 comments on commit bff18de

Please sign in to comment.