From eb2ba416411f72db57f5d006ffbcfd04bd810b5a Mon Sep 17 00:00:00 2001 From: AndriySvyryd Date: Mon, 21 Oct 2019 16:00:44 -0700 Subject: [PATCH] Map owned reference types to the same view as the owner by default. Fixes #18298 --- .../RelationalEntityTypeExtensions.cs | 20 +++++++++++++++-- .../Internal/MigrationsModelDiffer.cs | 22 ++++++++++++------- .../Internal/MigrationsModelDifferTest.cs | 15 +++++++++++++ 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs b/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs index 0bf18909b86..d694f114bfa 100644 --- a/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs @@ -289,10 +289,26 @@ public static bool IsIgnoredByMigrations([NotNull] this IEntityType entityType) return entityType.BaseType.IsIgnoredByMigrations(); } + if (entityType.GetDefiningQuery() != null) + { + return true; + } + var viewDefinition = entityType.FindAnnotation(RelationalAnnotationNames.ViewDefinition); + if (viewDefinition == null) + { + var ownership = entityType.FindOwnership(); + if (ownership != null + && ownership.IsUnique + && entityType.FindAnnotation(RelationalAnnotationNames.TableName) == null) + { + return ownership.PrincipalEntityType.IsIgnoredByMigrations(); + } + + return false; + } - return (viewDefinition != null && viewDefinition.Value == null) - || entityType.GetDefiningQuery() != null; + return viewDefinition.Value == null; } } } diff --git a/src/EFCore.Relational/Migrations/Internal/MigrationsModelDiffer.cs b/src/EFCore.Relational/Migrations/Internal/MigrationsModelDiffer.cs index 0f4412b5331..cbc9b7a0bce 100644 --- a/src/EFCore.Relational/Migrations/Internal/MigrationsModelDiffer.cs +++ b/src/EFCore.Relational/Migrations/Internal/MigrationsModelDiffer.cs @@ -2384,10 +2384,13 @@ public virtual TableMapping FindTargetTable(IEntityType entityType) /// 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. /// - public virtual T FindSource([NotNull] T target) - => _targetToSource.TryGetValue(target, out var source) - ? (T)source - : default; + public virtual T FindSource([CanBeNull] T target) + where T : class + => target == null + ? null + : _targetToSource.TryGetValue(target, out var source) + ? (T)source + : null; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -2425,10 +2428,13 @@ public virtual IProperty FindSource([NotNull] IProperty target) /// 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. /// - public virtual T FindTarget([NotNull] T source) - => _sourceToTarget.TryGetValue(source, out var target) - ? (T)target - : default; + public virtual T FindTarget([CanBeNull] T source) + where T : class + => source == null + ? null + : _sourceToTarget.TryGetValue(source, out var target) + ? (T)target + : null; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTest.cs b/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTest.cs index da1e023d4d1..322fbf33c06 100644 --- a/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTest.cs +++ b/test/EFCore.Relational.Tests/Migrations/Internal/MigrationsModelDifferTest.cs @@ -36,6 +36,21 @@ public void Model_differ_does_not_detect_views() result => Assert.Equal(0, result.Count)); } + [ConditionalFact] + public void Model_differ_does_not_detect_views_with_owned_types() + { + Execute( + _ => { }, + target => target.Entity( + x => + { + x.ToView("Orders"); + x.OwnsOne(y => y.Billing); + x.OwnsOne(y => y.Shipping); + }), + upOperations => Assert.Equal(0, upOperations.Count)); + } + [ConditionalFact] public void Model_differ_does_not_detect_queries() {