Skip to content

Commit

Permalink
Add quirk mode for issue #12227
Browse files Browse the repository at this point in the history
  • Loading branch information
AndriySvyryd committed Jul 11, 2018
1 parent 06c6a0a commit 036a773
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 67 deletions.
232 changes: 165 additions & 67 deletions src/EFCore.Specification.Tests/GraphUpdatesTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5734,101 +5734,199 @@ public virtual void Sometimes_not_calling_DetectChanges_when_required_does_not_t
});
}

[ConditionalFact]
public virtual void Can_add_valid_first_depedent_when_multiple_possible_principal_sides()
[ConditionalTheory]
[InlineData(true)]
[InlineData(false)]
public virtual void Can_add_valid_first_depedent_when_multiple_possible_principal_sides(bool quirk)
{
ExecuteWithStrategyInTransaction(
context =>
try
{
if (quirk)
{
var quizTask = new QuizTask();
quizTask.Choices.Add(new TaskChoice());
AppContext.SetSwitch("Microsoft.EntityFrameworkCore.Issue12227", true);
}

context.Add(quizTask);
ExecuteWithStrategyInTransaction(
context =>
{
var quizTask = new QuizTask();
quizTask.Choices.Add(new TaskChoice());
context.SaveChanges();
},
context =>
{
var quizTask = context.Set<QuizTask>().Include(e => e.Choices).Single();
if (quirk)
{
Assert.Throws<InvalidOperationException>(
() => context.Add(quizTask));
}
else
{
context.Add(quizTask);
}
Assert.Equal(quizTask.Id, quizTask.Choices.Single().QuestTaskId);
context.SaveChanges();
},
context =>
{
if (quirk)
{
Assert.Throws<InvalidOperationException>(
() => context.Set<QuizTask>().Include(e => e.Choices).Single());
}
else
{
var quizTask = context.Set<QuizTask>().Include(e => e.Choices).Single();
Assert.Same(quizTask.Choices.Single(), context.Set<TaskChoice>().Single());
Assert.Equal(quizTask.Id, quizTask.Choices.Single().QuestTaskId);
Assert.Empty(context.Set<HiddenAreaTask>().Include(e => e.Choices));
});
Assert.Same(quizTask.Choices.Single(), context.Set<TaskChoice>().Single());
Assert.Empty(context.Set<HiddenAreaTask>().Include(e => e.Choices));
}
});
}
finally
{
AppContext.SetSwitch("Microsoft.EntityFrameworkCore.Issue12227", false);
}
}

[ConditionalFact]
public virtual void Can_add_valid_second_depedent_when_multiple_possible_principal_sides()
[ConditionalTheory]
[InlineData(true)]
[InlineData(false)]
public virtual void Can_add_valid_second_depedent_when_multiple_possible_principal_sides(bool quirk)
{
ExecuteWithStrategyInTransaction(
context =>
try
{
if (quirk)
{
var hiddenAreaTask = new HiddenAreaTask();
hiddenAreaTask.Choices.Add(new TaskChoice());
AppContext.SetSwitch("Microsoft.EntityFrameworkCore.Issue12227", true);
}

context.Add(hiddenAreaTask);
ExecuteWithStrategyInTransaction(
context =>
{
var hiddenAreaTask = new HiddenAreaTask();
hiddenAreaTask.Choices.Add(new TaskChoice());
context.SaveChanges();
},
context =>
{
var hiddenAreaTask = context.Set<HiddenAreaTask>().Include(e => e.Choices).Single();
if (quirk)
{
Assert.Throws<InvalidOperationException>(
() => context.Add(hiddenAreaTask));
}
else
{
context.Add(hiddenAreaTask);
}
Assert.Equal(hiddenAreaTask.Id, hiddenAreaTask.Choices.Single().QuestTaskId);
context.SaveChanges();
},
context =>
{
if (quirk)
{
Assert.Throws<InvalidOperationException>(
() => context.Set<HiddenAreaTask>().Include(e => e.Choices).Single());
}
else
{
var hiddenAreaTask = context.Set<HiddenAreaTask>().Include(e => e.Choices).Single();
Assert.Same(hiddenAreaTask.Choices.Single(), context.Set<TaskChoice>().Single());
Assert.Equal(hiddenAreaTask.Id, hiddenAreaTask.Choices.Single().QuestTaskId);
Assert.Empty(context.Set<QuizTask>().Include(e => e.Choices));
});
Assert.Same(hiddenAreaTask.Choices.Single(), context.Set<TaskChoice>().Single());
Assert.Empty(context.Set<QuizTask>().Include(e => e.Choices));
}
});
}
finally
{
AppContext.SetSwitch("Microsoft.EntityFrameworkCore.Issue12227", false);
}
}

[ConditionalFact]
public virtual void Can_add_multiple_depedents_when_multiple_possible_principal_sides()
[ConditionalTheory]
[InlineData(true)]
[InlineData(false)]
public virtual void Can_add_multiple_depedents_when_multiple_possible_principal_sides(bool quirk)
{
ExecuteWithStrategyInTransaction(
context =>
try
{
if (quirk)
{
var quizTask = new QuizTask();
quizTask.Choices.Add(new TaskChoice());
quizTask.Choices.Add(new TaskChoice());
AppContext.SetSwitch("Microsoft.EntityFrameworkCore.Issue12227", true);
}

context.Add(quizTask);
ExecuteWithStrategyInTransaction(
context =>
{
var quizTask = new QuizTask();
quizTask.Choices.Add(new TaskChoice());
quizTask.Choices.Add(new TaskChoice());
var hiddenAreaTask = new HiddenAreaTask();
hiddenAreaTask.Choices.Add(new TaskChoice());
hiddenAreaTask.Choices.Add(new TaskChoice());
if (quirk)
{
Assert.Throws<InvalidOperationException>(
() => context.Add(quizTask));
}
else
{
context.Add(quizTask);
}
context.Add(hiddenAreaTask);
var hiddenAreaTask = new HiddenAreaTask();
hiddenAreaTask.Choices.Add(new TaskChoice());
hiddenAreaTask.Choices.Add(new TaskChoice());
context.SaveChanges();
},
context =>
{
var quizTask = context.Set<QuizTask>().Include(e => e.Choices).Single();
var hiddenAreaTask = context.Set<HiddenAreaTask>().Include(e => e.Choices).Single();
if (quirk)
{
Assert.Throws<InvalidOperationException>(
() => context.Add(hiddenAreaTask));
}
else
{
context.Add(hiddenAreaTask);
}
Assert.Equal(2, quizTask.Choices.Count);
foreach (var quizTaskChoice in quizTask.Choices)
context.SaveChanges();
},
context =>
{
Assert.Equal(quizTask.Id, quizTaskChoice.QuestTaskId);
}
if (quirk)
{
Assert.Throws<InvalidOperationException>(
() => context.Set<QuizTask>().Include(e => e.Choices).Single());
}
else
{
var quizTask = context.Set<QuizTask>().Include(e => e.Choices).Single();
var hiddenAreaTask = context.Set<HiddenAreaTask>().Include(e => e.Choices).Single();
Assert.Equal(2, hiddenAreaTask.Choices.Count);
foreach (var hiddenAreaTaskChoice in hiddenAreaTask.Choices)
{
Assert.Equal(hiddenAreaTask.Id, hiddenAreaTaskChoice.QuestTaskId);
}
Assert.Equal(2, quizTask.Choices.Count);
foreach (var quizTaskChoice in quizTask.Choices)
{
Assert.Equal(quizTask.Id, quizTaskChoice.QuestTaskId);
}
foreach (var taskChoice in context.Set<TaskChoice>())
{
Assert.Equal(
1,
quizTask.Choices.Count(e => e.Id == taskChoice.Id)
+ hiddenAreaTask.Choices.Count(e => e.Id == taskChoice.Id));
}
});
Assert.Equal(2, hiddenAreaTask.Choices.Count);
foreach (var hiddenAreaTaskChoice in hiddenAreaTask.Choices)
{
Assert.Equal(hiddenAreaTask.Id, hiddenAreaTaskChoice.QuestTaskId);
}
foreach (var taskChoice in context.Set<TaskChoice>())
{
Assert.Equal(
1,
quizTask.Choices.Count(e => e.Id == taskChoice.Id)
+ hiddenAreaTask.Choices.Count(e => e.Id == taskChoice.Id));
}
}
});
}
finally
{
AppContext.SetSwitch("Microsoft.EntityFrameworkCore.Issue12227", false);
}
}
}
}
19 changes: 19 additions & 0 deletions src/EFCore/ChangeTracking/Internal/NavigationFixer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,25 @@ private void InitialFixup(
{
if (!foreignKey.PrincipalEntityType.IsAssignableFrom(principalEntry.EntityType))
{
if (AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue12227", out var isEnabled) && isEnabled)
{
if (_sensitiveLoggingEnabled)
{
throw new InvalidOperationException(CoreStrings.IncompatiblePrincipalEntrySensitive(
entry.BuildCurrentValuesString(foreignKey.Properties),
entityType.DisplayName(),
entry.BuildOriginalValuesString(entityType.FindPrimaryKey().Properties),
principalEntry.EntityType.DisplayName(),
foreignKey.PrincipalEntityType.DisplayName()));
}

throw new InvalidOperationException(CoreStrings.IncompatiblePrincipalEntry(
Property.Format(foreignKey.Properties),
entityType.DisplayName(),
principalEntry.EntityType.DisplayName(),
foreignKey.PrincipalEntityType.DisplayName()));
}

conflictingPrincipalForeignKey = foreignKey;
}
else
Expand Down

0 comments on commit 036a773

Please sign in to comment.