Skip to content

Commit

Permalink
Add quirk mode for issue 12119
Browse files Browse the repository at this point in the history
  • Loading branch information
AndriySvyryd committed Jun 1, 2018
1 parent ef61273 commit f3a183e
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 76 deletions.
6 changes: 5 additions & 1 deletion src/EFCore/Metadata/Internal/InternalEntityTypeBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,11 @@ public virtual InternalKeyBuilder PrimaryKey(
else if (previousPrimaryKey != null
&& PropertyListComparer.Instance.Compare(previousPrimaryKey.Properties, properties) == 0)
{
previousPrimaryKey.UpdateConfigurationSource(configurationSource);
if (!AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue12119", out var isEnabled)
|| !isEnabled)
{
previousPrimaryKey.UpdateConfigurationSource(configurationSource);
}
return Metadata.SetPrimaryKey(properties, configurationSource).Builder;
}

Expand Down
226 changes: 166 additions & 60 deletions src/EFCore/Metadata/Internal/InternalModelBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,75 +63,151 @@ private InternalEntityTypeBuilder Entity(
? Metadata.FindEntityType(type.Name)
: Metadata.FindEntityType(clrType);

using (Metadata.ConventionDispatcher.StartBatch())
if (AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue12119", out var isEnabled)
&& isEnabled)
{
if (entityType != null)
if (entityType == null)
{
if (throwOnQuery && entityType.IsQueryType)
if (clrType == null)
{
if ((entityType.GetConfigurationSource() != ConfigurationSource.Explicit
|| configurationSource != ConfigurationSource.Explicit)
&& !RemoveEntityType(entityType, configurationSource))
if (Metadata.ShouldBeOwnedType(type.Name)
&& Metadata.HasEntityTypeWithDefiningNavigation(type.Name))
{
return null;
Debug.Assert(configurationSource == ConfigurationSource.Explicit,
"If a type is marked as an owned entity it can only be configured as a non-owned entity type explicitly");

Metadata.UnmarkAsOwnedType(type.Name);

using (Metadata.ConventionDispatcher.StartBatch())
{
foreach (var entityTypeWithDefiningNavigation in Metadata.GetEntityTypes(type.Name).ToList())
{
if (entityTypeWithDefiningNavigation.GetConfigurationSource() != ConfigurationSource.Explicit)
{
RemoveEntityType(entityTypeWithDefiningNavigation, configurationSource);
}
}

return Entity(type, configurationSource, throwOnQuery);
}
}

Metadata.Unignore(type.Name);

entityType = Metadata.AddEntityType(type.Name, configurationSource);
}
else
{
entityType.UpdateConfigurationSource(configurationSource);
return entityType.Builder;
}
}

if (clrType == null)
{
if (Metadata.ShouldBeOwnedType(type.Name)
&& Metadata.HasEntityTypeWithDefiningNavigation(type.Name))
{
Debug.Assert(configurationSource == ConfigurationSource.Explicit,
"If a type is marked as an owned entity it can only be configured as a non-owned entity type explicitly");
if (Metadata.ShouldBeOwnedType(clrType)
&& Metadata.HasEntityTypeWithDefiningNavigation(clrType))
{
Debug.Assert(configurationSource == ConfigurationSource.Explicit,
"If a type is marked as an owned entity it can only be configured as a non-owned entity type explicitly");

Metadata.UnmarkAsOwnedType(type.Name);
Metadata.UnmarkAsOwnedType(clrType);

foreach (var entityTypeWithDefiningNavigation in Metadata.GetEntityTypes(type.Name).ToList())
{
if (entityTypeWithDefiningNavigation.GetConfigurationSource() != ConfigurationSource.Explicit)
using (Metadata.ConventionDispatcher.StartBatch())
{
RemoveEntityType(entityTypeWithDefiningNavigation, configurationSource);
foreach (var entityTypeWithDefiningNavigation in Metadata.GetEntityTypes(clrType).ToList())
{
if (entityTypeWithDefiningNavigation.GetConfigurationSource() != ConfigurationSource.Explicit)
{
RemoveEntityType(entityTypeWithDefiningNavigation, configurationSource);
}
}

return Entity(type, configurationSource, throwOnQuery);
}
}

return Entity(type, configurationSource, throwOnQuery);
}

Metadata.Unignore(type.Name);
Metadata.Unignore(type.Name);

entityType = Metadata.AddEntityType(type.Name, configurationSource);
entityType = Metadata.AddEntityType(clrType, configurationSource);
}
}
else
{
if (Metadata.ShouldBeOwnedType(clrType)
&& Metadata.HasEntityTypeWithDefiningNavigation(clrType))
if (throwOnQuery && entityType.IsQueryType)
{
Debug.Assert(configurationSource == ConfigurationSource.Explicit,
"If a type is marked as an owned entity it can only be configured as a non-owned entity type explicitly");
throw new InvalidOperationException(
CoreStrings.CannotAccessQueryAsEntity(entityType.DisplayName()));
}

Metadata.UnmarkAsOwnedType(clrType);
entityType.UpdateConfigurationSource(configurationSource);
}
}
else
{
using (Metadata.ConventionDispatcher.StartBatch())
{
if (entityType != null)
{
if (throwOnQuery && entityType.IsQueryType)
{
if ((entityType.GetConfigurationSource() != ConfigurationSource.Explicit
|| configurationSource != ConfigurationSource.Explicit)
&& !RemoveEntityType(entityType, configurationSource))
{
return null;
}
}
else
{
entityType.UpdateConfigurationSource(configurationSource);
return entityType.Builder;
}
}

foreach (var entityTypeWithDefiningNavigation in Metadata.GetEntityTypes(clrType).ToList())
if (clrType == null)
{
if (Metadata.ShouldBeOwnedType(type.Name)
&& Metadata.HasEntityTypeWithDefiningNavigation(type.Name))
{
if (entityTypeWithDefiningNavigation.GetConfigurationSource() != ConfigurationSource.Explicit)
Debug.Assert(configurationSource == ConfigurationSource.Explicit,
"If a type is marked as an owned entity it can only be configured as a non-owned entity type explicitly");

Metadata.UnmarkAsOwnedType(type.Name);

foreach (var entityTypeWithDefiningNavigation in Metadata.GetEntityTypes(type.Name).ToList())
{
RemoveEntityType(entityTypeWithDefiningNavigation, configurationSource);
if (entityTypeWithDefiningNavigation.GetConfigurationSource() != ConfigurationSource.Explicit)
{
RemoveEntityType(entityTypeWithDefiningNavigation, configurationSource);
}
}

return Entity(type, configurationSource, throwOnQuery);
}

return Entity(type, configurationSource, throwOnQuery);
Metadata.Unignore(type.Name);

entityType = Metadata.AddEntityType(type.Name, configurationSource);
}
else
{
if (Metadata.ShouldBeOwnedType(clrType)
&& Metadata.HasEntityTypeWithDefiningNavigation(clrType))
{
Debug.Assert(configurationSource == ConfigurationSource.Explicit,
"If a type is marked as an owned entity it can only be configured as a non-owned entity type explicitly");

Metadata.Unignore(type.Name);
Metadata.UnmarkAsOwnedType(clrType);

foreach (var entityTypeWithDefiningNavigation in Metadata.GetEntityTypes(clrType).ToList())
{
if (entityTypeWithDefiningNavigation.GetConfigurationSource() != ConfigurationSource.Explicit)
{
RemoveEntityType(entityTypeWithDefiningNavigation, configurationSource);
}
}

entityType = Metadata.AddEntityType(clrType, configurationSource);
return Entity(type, configurationSource, throwOnQuery);
}

Metadata.Unignore(type.Name);

entityType = Metadata.AddEntityType(clrType, configurationSource);
}
}
}

Expand All @@ -144,38 +220,68 @@ private InternalEntityTypeBuilder Entity(
/// </summary>
public virtual InternalEntityTypeBuilder Query([NotNull] Type clrType, ConfigurationSource configurationSource)
{
if (IsIgnored(clrType, configurationSource))
if (AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue12119", out var isEnabled)
&& isEnabled)
{
return null;
}
if (IsIgnored(clrType, ConfigurationSource.Explicit))
{
return null;
}

var entityType = Metadata.FindEntityType(clrType);
var entityType = Metadata.FindEntityType(clrType);

using (Metadata.ConventionDispatcher.StartBatch())
{
if (entityType != null)
if (entityType == null)
{
Metadata.Unignore(clrType);

entityType = Metadata.AddQueryType(clrType);
}
else
{
if (!entityType.IsQueryType)
{
if ((entityType.GetConfigurationSource() != ConfigurationSource.Explicit
|| configurationSource != ConfigurationSource.Explicit)
&& !RemoveEntityType(entityType, configurationSource))
{
return null;
}
throw new InvalidOperationException(
CoreStrings.CannotAccessEntityAsQuery(entityType.DisplayName()));
}
else
}

return entityType.Builder;
}
else
{
if (IsIgnored(clrType, configurationSource))
{
return null;
}

var entityType = Metadata.FindEntityType(clrType);

using (Metadata.ConventionDispatcher.StartBatch())
{
if (entityType != null)
{
entityType.UpdateConfigurationSource(configurationSource);
return entityType.Builder;
if (!entityType.IsQueryType)
{
if ((entityType.GetConfigurationSource() != ConfigurationSource.Explicit
|| configurationSource != ConfigurationSource.Explicit)
&& !RemoveEntityType(entityType, configurationSource))
{
return null;
}
}
else
{
entityType.UpdateConfigurationSource(configurationSource);
return entityType.Builder;
}
}
}

Metadata.Unignore(clrType);
Metadata.Unignore(clrType);

entityType = Metadata.AddQueryType(clrType, configurationSource);
entityType = Metadata.AddQueryType(clrType, configurationSource);

return entityType.Builder;
return entityType.Builder;
}
}
}

Expand Down
35 changes: 24 additions & 11 deletions src/EFCore/Metadata/Internal/Model.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,25 +157,38 @@ private EntityType AddEntityType(EntityType entityType)
throw new InvalidOperationException(CoreStrings.ClashingWeakEntityType(entityType.DisplayName()));
}

if (_entityTypes.TryGetValue(entityTypeName, out var clashingEntityType))
if (AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue12119", out var isEnabled)
&& isEnabled)
{
if (clashingEntityType.IsQueryType)
var previousLength = _entityTypes.Count;
_entityTypes[entityTypeName] = entityType;
if (previousLength == _entityTypes.Count)
{
throw new InvalidOperationException(CoreStrings.DuplicateEntityType(entityType.DisplayName()));
}
}
else
{
if (_entityTypes.TryGetValue(entityTypeName, out var clashingEntityType))
{
if (clashingEntityType.IsQueryType)
{
if (entityType.IsQueryType)
{
throw new InvalidOperationException(CoreStrings.DuplicateQueryType(entityType.DisplayName()));
}
throw new InvalidOperationException(CoreStrings.CannotAccessQueryAsEntity(entityType.DisplayName()));
}

if (entityType.IsQueryType)
{
throw new InvalidOperationException(CoreStrings.DuplicateQueryType(entityType.DisplayName()));
throw new InvalidOperationException(CoreStrings.CannotAccessEntityAsQuery(entityType.DisplayName()));
}
throw new InvalidOperationException(CoreStrings.CannotAccessQueryAsEntity(entityType.DisplayName()));
throw new InvalidOperationException(CoreStrings.DuplicateEntityType(entityType.DisplayName()));
}

if (entityType.IsQueryType)
{
throw new InvalidOperationException(CoreStrings.CannotAccessEntityAsQuery(entityType.DisplayName()));
}
throw new InvalidOperationException(CoreStrings.DuplicateEntityType(entityType.DisplayName()));
_entityTypes.Add(entityTypeName, entityType);
}

_entityTypes.Add(entityTypeName, entityType);
}

return ConventionDispatcher.OnEntityTypeAdded(entityType.Builder)?.Metadata;
Expand Down
Loading

0 comments on commit f3a183e

Please sign in to comment.