diff --git a/src/Microsoft.EntityFrameworkCore.Commands/Migrations/Design/CSharpSnapshotGenerator.cs b/src/Microsoft.EntityFrameworkCore.Commands/Migrations/Design/CSharpSnapshotGenerator.cs
index 3f6b051e157..4da7010a315 100644
--- a/src/Microsoft.EntityFrameworkCore.Commands/Migrations/Design/CSharpSnapshotGenerator.cs
+++ b/src/Microsoft.EntityFrameworkCore.Commands/Migrations/Design/CSharpSnapshotGenerator.cs
@@ -467,7 +467,16 @@ protected virtual void GenerateForeignKey(
stringBuilder
.AppendLine()
.Append("b.HasOne(")
- .Append(_code.Literal(foreignKey.PrincipalEntityType.Name))
+ .Append(_code.Literal(foreignKey.PrincipalEntityType.Name));
+
+ if (foreignKey.DependentToPrincipal != null)
+ {
+ stringBuilder
+ .Append(", ")
+ .Append(_code.Literal(foreignKey.DependentToPrincipal.Name));
+ }
+
+ stringBuilder
.Append(")")
.AppendLine();
@@ -476,7 +485,16 @@ protected virtual void GenerateForeignKey(
if (foreignKey.IsUnique)
{
stringBuilder
- .AppendLine(".WithOne()")
+ .Append(".WithOne(");
+
+ if (foreignKey.PrincipalToDependent != null)
+ {
+ stringBuilder
+ .Append(_code.Literal(foreignKey.PrincipalToDependent.Name));
+ }
+
+ stringBuilder
+ .AppendLine(")")
.Append(".HasForeignKey(")
.Append(_code.Literal(foreignKey.DeclaringEntityType.Name))
.Append(", ")
@@ -499,7 +517,16 @@ protected virtual void GenerateForeignKey(
else
{
stringBuilder
- .AppendLine(".WithMany()")
+ .Append(".WithMany(");
+
+ if (foreignKey.PrincipalToDependent != null)
+ {
+ stringBuilder
+ .Append(_code.Literal(foreignKey.PrincipalToDependent.Name));
+ }
+
+ stringBuilder
+ .AppendLine(")")
.Append(".HasForeignKey(")
.Append(string.Join(", ", foreignKey.Properties.Select(p => _code.Literal(p.Name))))
.Append(")");
diff --git a/src/Microsoft.EntityFrameworkCore/Metadata/Internal/EntityType.cs b/src/Microsoft.EntityFrameworkCore/Metadata/Internal/EntityType.cs
index fdd6623ba81..e43ba477265 100644
--- a/src/Microsoft.EntityFrameworkCore/Metadata/Internal/EntityType.cs
+++ b/src/Microsoft.EntityFrameworkCore/Metadata/Internal/EntityType.cs
@@ -848,18 +848,28 @@ public virtual Navigation AddNavigation(
Debug.Assert((pointsToPrincipal ? foreignKey.DeclaringEntityType : foreignKey.PrincipalEntityType) == this,
"EntityType mismatch");
- Navigation.IsCompatible(
- name,
- this,
- pointsToPrincipal ? foreignKey.PrincipalEntityType : foreignKey.DeclaringEntityType,
- !pointsToPrincipal && !foreignKey.IsUnique,
- shouldThrow: true);
-
- // TODO: use this value for IsCompatible call
- var navigationProperty = ClrType.GetPropertiesInHierarchy(name).FirstOrDefault();
- Debug.Assert(navigationProperty != null);
-
- var navigation = new Navigation(navigationProperty, foreignKey);
+ Navigation navigation = null;
+
+ if (ClrType != null)
+ {
+ Navigation.IsCompatible(
+ name,
+ this,
+ pointsToPrincipal ? foreignKey.PrincipalEntityType : foreignKey.DeclaringEntityType,
+ !pointsToPrincipal && !foreignKey.IsUnique,
+ shouldThrow: true);
+
+ // TODO: use this value for IsCompatible call
+ var navigationProperty = ClrType.GetPropertiesInHierarchy(name).FirstOrDefault();
+ Debug.Assert(navigationProperty != null);
+
+ navigation = new Navigation(navigationProperty, foreignKey);
+ }
+ else
+ {
+ navigation = new Navigation(name, foreignKey);
+ }
+
_navigations.Add(name, navigation);
PropertyMetadataChanged();
diff --git a/src/Microsoft.EntityFrameworkCore/Metadata/Internal/Navigation.cs b/src/Microsoft.EntityFrameworkCore/Metadata/Internal/Navigation.cs
index 612f5051f79..bf370529ca5 100644
--- a/src/Microsoft.EntityFrameworkCore/Metadata/Internal/Navigation.cs
+++ b/src/Microsoft.EntityFrameworkCore/Metadata/Internal/Navigation.cs
@@ -36,6 +36,15 @@ public Navigation([NotNull] PropertyInfo navigationProperty, [NotNull] ForeignKe
ForeignKey = foreignKey;
}
+ public Navigation([NotNull] string navigationName, [NotNull] ForeignKey foreignKey)
+ {
+ Check.NotEmpty(navigationName, nameof(navigationName));
+ Check.NotNull(foreignKey, nameof(foreignKey));
+
+ Name = navigationName;
+ ForeignKey = foreignKey;
+ }
+
public virtual string Name { get; }
public virtual ForeignKey ForeignKey { get; }
@@ -96,12 +105,8 @@ public static bool IsCompatible(
var sourceClrType = sourceType.ClrType;
if (sourceClrType == null)
{
- if (shouldThrow)
- {
- throw new InvalidOperationException(
- CoreStrings.NavigationOnShadowEntity(navigationPropertyName, sourceType.DisplayName()));
- }
- return false;
+ // Navigation defined on shadow entity type.
+ return true;
}
var targetClrType = targetType.ClrType;
diff --git a/src/Microsoft.EntityFrameworkCore/Properties/CoreStrings.Designer.cs b/src/Microsoft.EntityFrameworkCore/Properties/CoreStrings.Designer.cs
index f54ad3d5bc9..239f19e0635 100644
--- a/src/Microsoft.EntityFrameworkCore/Properties/CoreStrings.Designer.cs
+++ b/src/Microsoft.EntityFrameworkCore/Properties/CoreStrings.Designer.cs
@@ -228,15 +228,6 @@ public static string NoValueGenerator([CanBeNull] object property, [CanBeNull] o
return string.Format(CultureInfo.CurrentCulture, GetString("NoValueGenerator", "property", "entityType", "propertyType"), property, entityType, propertyType);
}
- ///
- /// The property '{property}' on entity type '{entityType}' has a temporary value. Either set a permanent value explicitly or ensure that the database is configured to generate values for this property.
- ///
- public static string TempValue([CanBeNull] object property, [CanBeNull] object entityType)
- {
- return string.Format(CultureInfo.CurrentCulture, GetString("TempValue", "property", "entityType"), property, entityType);
- }
-
-
///
/// The property '{property}' on entity type '{entityType}' has a temporary value while attempting to change the entity's state to '{state}'. Either set a permanent value explicitly or ensure that the database is configured to generate values for this property.
///
@@ -325,14 +316,6 @@ public static string DuplicateNavigation([CanBeNull] object navigation, [CanBeNu
return string.Format(CultureInfo.CurrentCulture, GetString("DuplicateNavigation", "navigation", "entityType", "duplicateEntityType"), navigation, entityType, duplicateEntityType);
}
- ///
- /// The navigation property '{navigation}' cannot be added to the entity type '{entityType}' because the entity type is defined in shadow state and navigations properties cannot be added to shadow state.
- ///
- public static string NavigationOnShadowEntity([CanBeNull] object navigation, [CanBeNull] object entityType)
- {
- return string.Format(CultureInfo.CurrentCulture, GetString("NavigationOnShadowEntity", "navigation", "entityType"), navigation, entityType);
- }
-
///
/// The navigation property '{navigation}' cannot be added to the entity type '{entityType}' because there is no corresponding CLR property on the underlying type and navigations properties cannot be added to shadow state.
///
@@ -1157,6 +1140,14 @@ public static string NoPropertyType([CanBeNull] object property, [CanBeNull] obj
return string.Format(CultureInfo.CurrentCulture, GetString("NoPropertyType", "property", "entityType"), property, entityType);
}
+ ///
+ /// The property '{property}' on entity type '{entityType}' has a temporary value. Either set a permanent value explicitly or ensure that the database is configured to generate values for this property.
+ ///
+ public static string TempValue([CanBeNull] object property, [CanBeNull] object entityType)
+ {
+ return string.Format(CultureInfo.CurrentCulture, GetString("TempValue", "property", "entityType"), property, entityType);
+ }
+
private static string GetString(string name, params string[] formatterNames)
{
var value = _resourceManager.GetString(name);
diff --git a/src/Microsoft.EntityFrameworkCore/Properties/CoreStrings.resx b/src/Microsoft.EntityFrameworkCore/Properties/CoreStrings.resx
index fb382c25a1b..a6d69bfd1e6 100644
--- a/src/Microsoft.EntityFrameworkCore/Properties/CoreStrings.resx
+++ b/src/Microsoft.EntityFrameworkCore/Properties/CoreStrings.resx
@@ -231,9 +231,6 @@
The navigation property '{navigation}' cannot be added to the entity type '{entityType}' because a navigation property with the same name already exists on entity type '{duplicateEntityType}'.
-
- The navigation property '{navigation}' cannot be added to the entity type '{entityType}' because the entity type is defined in shadow state and navigations properties cannot be added to shadow state.
-
The navigation property '{navigation}' cannot be added to the entity type '{entityType}' because there is no corresponding CLR property on the underlying type and navigations properties cannot be added to shadow state.
diff --git a/test/Microsoft.EntityFrameworkCore.Commands.FunctionalTests/Migrations/ModelSnapshotTest.cs b/test/Microsoft.EntityFrameworkCore.Commands.FunctionalTests/Migrations/ModelSnapshotTest.cs
index f201a244800..32977a763b8 100644
--- a/test/Microsoft.EntityFrameworkCore.Commands.FunctionalTests/Migrations/ModelSnapshotTest.cs
+++ b/test/Microsoft.EntityFrameworkCore.Commands.FunctionalTests/Migrations/ModelSnapshotTest.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.EntityFrameworkCore.Specification.Tests;
@@ -21,12 +22,14 @@ public class ModelSnapshotTest
private class EntityWithOneProperty
{
public int Id { get; set; }
+ public EntityWithTwoProperties EntityWithTwoProperties { get; set; }
}
private class EntityWithTwoProperties
{
public int Id { get; set; }
public int AlternateId { get; set; }
+ public EntityWithOneProperty EntityWithOneProperty { get; set; }
}
private class EntityWithStringProperty
@@ -38,6 +41,7 @@ private class EntityWithStringProperty
private class EntityWithStringKey
{
public string Id { get; set; }
+ public ICollection Properties { get; set; }
}
private class EntityWithGenericKey
@@ -140,8 +144,8 @@ public void Entities_are_stored_in_model_snapshot()
Test(
builder =>
{
- builder.Entity();
- builder.Entity();
+ builder.Entity().Ignore(e => e.EntityWithTwoProperties);
+ builder.Entity().Ignore(e => e.EntityWithOneProperty);
},
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithOneProperty"", b =>
@@ -184,7 +188,11 @@ public void Entities_are_stored_in_model_snapshot()
public void EntityType_annotations_are_stored_in_snapshot()
{
Test(
- builder => { builder.Entity().HasAnnotation("AnnotationName", "AnnotationValue"); },
+ builder =>
+ {
+ builder.Entity().HasAnnotation("AnnotationName", "AnnotationValue");
+ builder.Ignore();
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithOneProperty"", b =>
{
@@ -322,7 +330,11 @@ public void Discriminator_annotations_are_stored_in_snapshot()
public void Properties_are_stored_in_snapshot()
{
Test(
- builder => { builder.Entity(); },
+ builder =>
+ {
+ builder.Entity();
+ builder.Ignore();
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
@@ -351,7 +363,11 @@ public void Properties_are_stored_in_snapshot()
public void Primary_key_is_stored_in_snapshot()
{
Test(
- builder => { builder.Entity().HasKey(t => new { t.Id, t.AlternateId }); },
+ builder =>
+ {
+ builder.Entity().HasKey(t => new { t.Id, t.AlternateId });
+ builder.Ignore();
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
@@ -379,7 +395,11 @@ public void Primary_key_is_stored_in_snapshot()
public void Alternate_keys_are_stored_in_snapshot()
{
Test(
- builder => { builder.Entity().HasAlternateKey(t => new { t.Id, t.AlternateId }); },
+ builder =>
+ {
+ builder.Entity().HasAlternateKey(t => new { t.Id, t.AlternateId });
+ builder.Ignore();
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
@@ -409,7 +429,11 @@ public void Alternate_keys_are_stored_in_snapshot()
public void Indexes_are_stored_in_snapshot()
{
Test(
- builder => { builder.Entity().HasIndex(t => t.AlternateId); },
+ builder =>
+ {
+ builder.Entity().HasIndex(t => t.AlternateId);
+ builder.Ignore();
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
@@ -436,7 +460,11 @@ public void Indexes_are_stored_in_snapshot()
public void Indexes_are_stored_in_snapshot_including_composite_index()
{
Test(
- builder => { builder.Entity().HasIndex(t => new { t.Id, t.AlternateId }); },
+ builder =>
+ {
+ builder.Entity().HasIndex(t => new { t.Id, t.AlternateId });
+ builder.Ignore();
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
@@ -466,7 +494,14 @@ public void Indexes_are_stored_in_snapshot_including_composite_index()
public void Foreign_keys_are_stored_in_snapshot()
{
Test(
- builder => { builder.Entity().HasOne().WithOne().HasForeignKey(e => e.AlternateId); },
+ builder =>
+ {
+ builder
+ .Entity()
+ .HasOne(e => e.EntityWithOneProperty)
+ .WithOne(e => e.EntityWithTwoProperties)
+ .HasForeignKey(e => e.AlternateId);
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithOneProperty"", b =>
{
@@ -494,16 +529,18 @@ public void Foreign_keys_are_stored_in_snapshot()
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
- b.HasOne(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithOneProperty"")
- .WithOne()
+ b.HasOne(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithOneProperty"", ""EntityWithOneProperty"")
+ .WithOne(""EntityWithTwoProperties"")
.HasForeignKey(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", ""AlternateId"")
.OnDelete(DeleteBehavior.Cascade);
});
",
o =>
{
- Assert.Equal(1, o.FindEntityType(typeof(EntityWithTwoProperties)).GetForeignKeys().Count());
- Assert.Equal("AlternateId", o.FindEntityType(typeof(EntityWithTwoProperties)).GetForeignKeys().First().Properties[0].Name);
+ var foreignKey = o.FindEntityType(typeof(EntityWithTwoProperties)).GetForeignKeys().Single();
+ Assert.Equal("AlternateId", foreignKey.Properties[0].Name);
+ Assert.Equal("EntityWithTwoProperties", foreignKey.PrincipalToDependent.Name);
+ Assert.Equal("EntityWithOneProperty", foreignKey.DependentToPrincipal.Name);
});
}
@@ -513,9 +550,11 @@ public void Relationship_principal_key_is_stored_in_snapshot()
Test(
builder =>
{
- builder.Entity().HasOne().WithOne()
- .HasForeignKey(e => e.Id).
- HasPrincipalKey(e => e.AlternateId);
+ builder.Entity()
+ .HasOne(e => e.EntityWithTwoProperties)
+ .WithOne(e => e.EntityWithOneProperty)
+ .HasForeignKey(e => e.Id)
+ .HasPrincipalKey(e => e.AlternateId);
},
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithOneProperty"", b =>
@@ -543,8 +582,8 @@ public void Relationship_principal_key_is_stored_in_snapshot()
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithOneProperty"", b =>
{
- b.HasOne(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"")
- .WithOne()
+ b.HasOne(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", ""EntityWithTwoProperties"")
+ .WithOne(""EntityWithOneProperty"")
.HasForeignKey(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithOneProperty"", ""Id"")
.HasPrincipalKey(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", ""AlternateId"")
.OnDelete(DeleteBehavior.Cascade);
@@ -553,7 +592,7 @@ public void Relationship_principal_key_is_stored_in_snapshot()
o =>
{
Assert.Equal(2, o.FindEntityType(typeof(EntityWithTwoProperties)).GetKeys().Count());
- Assert.True(o.FindEntityType(typeof(EntityWithTwoProperties)).GetKeys().Any(k => k.Properties.Any(p => p.Name == "AlternateId")));
+ Assert.True(o.FindEntityType(typeof(EntityWithTwoProperties)).FindProperty("AlternateId").IsKey());
});
}
@@ -674,7 +713,11 @@ public void AlternateKey_name_preserved_when_generic()
public void Property_annotations_are_stored_in_snapshot()
{
Test(
- builder => { builder.Entity().Property("Id").HasAnnotation("AnnotationName", "AnnotationValue"); },
+ builder =>
+ {
+ builder.Entity().Property("Id").HasAnnotation("AnnotationName", "AnnotationValue");
+ builder.Ignore();
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithOneProperty"", b =>
{
@@ -717,7 +760,11 @@ public void Property_isNullable_is_stored_in_snapshot()
public void Property_ValueGenerated_value_is_stored_in_snapshot()
{
Test(
- builder => { builder.Entity().Property("AlternateId").ValueGeneratedOnAdd(); },
+ builder =>
+ {
+ builder.Entity().Property("AlternateId").ValueGeneratedOnAdd();
+ builder.Ignore();
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
@@ -761,7 +808,11 @@ public void Property_maxLength_is_stored_in_snapshot()
public void Property_RequiresValueGenerator_is_not_stored_in_snapshot()
{
Test(
- builder => { builder.Entity().Property("AlternateId").Metadata.RequiresValueGenerator = true; },
+ builder =>
+ {
+ builder.Entity().Property("AlternateId").Metadata.RequiresValueGenerator = true;
+ builder.Ignore();
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
@@ -782,7 +833,11 @@ public void Property_RequiresValueGenerator_is_not_stored_in_snapshot()
public void Property_concurrencyToken_is_stored_in_snapshot()
{
Test(
- builder => { builder.Entity().Property("AlternateId").IsConcurrencyToken(); },
+ builder =>
+ {
+ builder.Entity().Property("AlternateId").IsConcurrencyToken();
+ builder.Ignore();
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
@@ -804,7 +859,11 @@ public void Property_concurrencyToken_is_stored_in_snapshot()
public void Property_column_name_annotation_is_stored_in_snapshot_as_fluent_api()
{
Test(
- builder => { builder.Entity().Property("AlternateId").HasColumnName("CName"); },
+ builder =>
+ {
+ builder.Entity().Property("AlternateId").HasColumnName("CName");
+ builder.Ignore();
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
@@ -826,7 +885,11 @@ public void Property_column_name_annotation_is_stored_in_snapshot_as_fluent_api(
public void Property_column_type_annotation_is_stored_in_snapshot_as_fluent_api()
{
Test(
- builder => { builder.Entity().Property("AlternateId").HasColumnType("CType"); },
+ builder =>
+ {
+ builder.Entity().Property("AlternateId").HasColumnType("CType");
+ builder.Ignore();
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
@@ -848,7 +911,11 @@ public void Property_column_type_annotation_is_stored_in_snapshot_as_fluent_api(
public void Property_default_value_annotation_is_stored_in_snapshot_as_fluent_api()
{
Test(
- builder => { builder.Entity().Property("AlternateId").HasDefaultValue(1); },
+ builder =>
+ {
+ builder.Entity().Property("AlternateId").HasDefaultValue(1);
+ builder.Ignore();
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
@@ -871,7 +938,11 @@ public void Property_default_value_annotation_is_stored_in_snapshot_as_fluent_ap
public void Property_default_value_sql_annotation_is_stored_in_snapshot_as_fluent_api()
{
Test(
- builder => { builder.Entity().Property("AlternateId").HasDefaultValueSql("SQL"); },
+ builder =>
+ {
+ builder.Entity().Property("AlternateId").HasDefaultValueSql("SQL");
+ builder.Ignore();
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
@@ -894,7 +965,11 @@ public void Property_default_value_sql_annotation_is_stored_in_snapshot_as_fluen
public void Property_computed_column_sql_annotation_is_stored_in_snapshot_as_fluent_api()
{
Test(
- builder => { builder.Entity().Property("AlternateId").HasComputedColumnSql("SQL"); },
+ builder =>
+ {
+ builder.Entity().Property("AlternateId").HasComputedColumnSql("SQL");
+ builder.Ignore();
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
@@ -940,7 +1015,11 @@ public void Property_default_value_of_enum_type_is_stored_in_snapshot_without_ac
public void Property_multiple_annotations_are_stored_in_snapshot()
{
Test(
- builder => { builder.Entity().Property("AlternateId").HasColumnName("CName").HasAnnotation("AnnotationName", "AnnotationValue"); },
+ builder =>
+ {
+ builder.Entity().Property("AlternateId").HasColumnName("CName").HasAnnotation("AnnotationName", "AnnotationValue");
+ builder.Ignore();
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
@@ -973,7 +1052,11 @@ public void Property_multiple_annotations_are_stored_in_snapshot()
public void Key_annotations_are_stored_in_snapshot()
{
Test(
- builder => { builder.Entity().HasAlternateKey(t => t.AlternateId).HasAnnotation("AnnotationName", "AnnotationValue"); },
+ builder =>
+ {
+ builder.Entity().HasAlternateKey(t => t.AlternateId).HasAnnotation("AnnotationName", "AnnotationValue");
+ builder.Ignore();
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
@@ -997,7 +1080,11 @@ public void Key_annotations_are_stored_in_snapshot()
public void Key_name_annotation_is_stored_in_snapshot_as_fluent_api()
{
Test(
- builder => { builder.Entity().HasAlternateKey(t => t.AlternateId).HasName("KeyName"); },
+ builder =>
+ {
+ builder.Entity().HasAlternateKey(t => t.AlternateId).HasName("KeyName");
+ builder.Ignore();
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
@@ -1021,7 +1108,11 @@ public void Key_name_annotation_is_stored_in_snapshot_as_fluent_api()
public void Key_multiple_annotations_are_stored_in_snapshot()
{
Test(
- builder => { builder.Entity().HasAlternateKey(t => t.AlternateId).HasName("IndexName").HasAnnotation("AnnotationName", "AnnotationValue"); },
+ builder =>
+ {
+ builder.Entity().HasAlternateKey(t => t.AlternateId).HasName("IndexName").HasAnnotation("AnnotationName", "AnnotationValue");
+ builder.Ignore();
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
@@ -1056,7 +1147,11 @@ public void Key_multiple_annotations_are_stored_in_snapshot()
public void Index_annotations_are_stored_in_snapshot()
{
Test(
- builder => { builder.Entity().HasIndex(t => t.AlternateId).HasAnnotation("AnnotationName", "AnnotationValue"); },
+ builder =>
+ {
+ builder.Entity().HasIndex(t => t.AlternateId).HasAnnotation("AnnotationName", "AnnotationValue");
+ builder.Ignore();
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
@@ -1080,7 +1175,11 @@ public void Index_annotations_are_stored_in_snapshot()
public void Index_isUnique_is_stored_in_snapshot()
{
Test(
- builder => { builder.Entity().HasIndex(t => t.AlternateId).IsUnique(); },
+ builder =>
+ {
+ builder.Entity().HasIndex(t => t.AlternateId).IsUnique();
+ builder.Ignore();
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
@@ -1104,7 +1203,11 @@ public void Index_isUnique_is_stored_in_snapshot()
public void Index_name_annotation_is_stored_in_snapshot_as_fluent_api()
{
Test(
- builder => { builder.Entity().HasIndex(t => t.AlternateId).HasName("IndexName"); },
+ builder =>
+ {
+ builder.Entity().HasIndex(t => t.AlternateId).HasName("IndexName");
+ builder.Ignore();
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
@@ -1128,7 +1231,11 @@ public void Index_name_annotation_is_stored_in_snapshot_as_fluent_api()
public void Index_multiple_annotations_are_stored_in_snapshot()
{
Test(
- builder => { builder.Entity().HasIndex(t => t.AlternateId).HasName("IndexName").HasAnnotation("AnnotationName", "AnnotationValue"); },
+ builder =>
+ {
+ builder.Entity().HasIndex(t => t.AlternateId).HasName("IndexName").HasAnnotation("AnnotationName", "AnnotationValue");
+ builder.Ignore();
+ },
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
@@ -1166,8 +1273,8 @@ public void ForeignKey_annotations_are_stored_in_snapshot()
builder =>
{
builder.Entity()
- .HasOne()
- .WithOne()
+ .HasOne(e => e.EntityWithOneProperty)
+ .WithOne(e => e.EntityWithTwoProperties)
.HasForeignKey(e => e.AlternateId)
.HasAnnotation("AnnotationName", "AnnotationValue");
},
@@ -1198,8 +1305,8 @@ public void ForeignKey_annotations_are_stored_in_snapshot()
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
- b.HasOne(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithOneProperty"")
- .WithOne()
+ b.HasOne(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithOneProperty"", ""EntityWithOneProperty"")
+ .WithOne(""EntityWithTwoProperties"")
.HasForeignKey(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", ""AlternateId"")
.HasAnnotation(""AnnotationName"", ""AnnotationValue"")
.OnDelete(DeleteBehavior.Cascade);
@@ -1214,6 +1321,7 @@ public void ForeignKey_isRequired_is_stored_in_snapshot()
Test(
builder =>
{
+ builder.Entity().Ignore(e => e.Properties);
builder.Entity()
.HasOne()
.WithOne()
@@ -1264,7 +1372,7 @@ public void ForeignKey_isUnique_is_stored_in_snapshot()
{
builder.Entity()
.HasOne()
- .WithMany()
+ .WithMany(e => e.Properties)
.HasForeignKey(e => e.Name);
},
@"
@@ -1294,7 +1402,7 @@ public void ForeignKey_isUnique_is_stored_in_snapshot()
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithStringProperty"", b =>
{
b.HasOne(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithStringKey"")
- .WithMany()
+ .WithMany(""Properties"")
.HasForeignKey(""Name"");
});
",
@@ -1308,9 +1416,10 @@ public void ForeignKey_deleteBehavior_is_stored_in_snapshot()
builder =>
{
builder.Entity()
- .HasOne()
+ .HasOne(e => e.EntityWithTwoProperties)
.WithMany()
.HasForeignKey(e => e.Id);
+ builder.Entity().Ignore(e => e.EntityWithOneProperty);
},
@"
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithOneProperty"", b =>
@@ -1338,7 +1447,7 @@ public void ForeignKey_deleteBehavior_is_stored_in_snapshot()
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithOneProperty"", b =>
{
- b.HasOne(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"")
+ b.HasOne(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", ""EntityWithTwoProperties"")
.WithMany()
.HasForeignKey(""Id"")
.OnDelete(DeleteBehavior.Cascade);
@@ -1354,8 +1463,8 @@ public void ForeignKey_deleteBehavior_is_stored_in_snapshot_for_one_to_one()
builder =>
{
builder.Entity()
- .HasOne()
- .WithOne()
+ .HasOne(e => e.EntityWithTwoProperties)
+ .WithOne(e => e.EntityWithOneProperty)
.HasForeignKey(e => e.Id);
},
@"
@@ -1384,8 +1493,8 @@ public void ForeignKey_deleteBehavior_is_stored_in_snapshot_for_one_to_one()
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithOneProperty"", b =>
{
- b.HasOne(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"")
- .WithOne()
+ b.HasOne(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", ""EntityWithTwoProperties"")
+ .WithOne(""EntityWithOneProperty"")
.HasForeignKey(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithOneProperty"", ""Id"")
.OnDelete(DeleteBehavior.Cascade);
});
@@ -1474,8 +1583,8 @@ public void ForeignKey_constraint_name_is_stored_in_snapshot_as_fluent_api()
builder =>
{
builder.Entity()
- .HasOne()
- .WithOne()
+ .HasOne(e => e.EntityWithOneProperty)
+ .WithOne(e => e.EntityWithTwoProperties)
.HasForeignKey(e => e.AlternateId)
.HasConstraintName("Constraint");
},
@@ -1506,8 +1615,8 @@ public void ForeignKey_constraint_name_is_stored_in_snapshot_as_fluent_api()
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
- b.HasOne(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithOneProperty"")
- .WithOne()
+ b.HasOne(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithOneProperty"", ""EntityWithOneProperty"")
+ .WithOne(""EntityWithTwoProperties"")
.HasForeignKey(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", ""AlternateId"")
.HasConstraintName(""Constraint"")
.OnDelete(DeleteBehavior.Cascade);
@@ -1523,8 +1632,8 @@ public void ForeignKey_multiple_annotations_are_stored_in_snapshot()
builder =>
{
builder.Entity()
- .HasOne()
- .WithOne()
+ .HasOne(e => e.EntityWithOneProperty)
+ .WithOne(e => e.EntityWithTwoProperties)
.HasForeignKey(e => e.AlternateId)
.HasAnnotation("AnnotationName", "AnnotationValue")
.HasConstraintName("Constraint");
@@ -1556,8 +1665,8 @@ public void ForeignKey_multiple_annotations_are_stored_in_snapshot()
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", b =>
{
- b.HasOne(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithOneProperty"")
- .WithOne()
+ b.HasOne(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithOneProperty"", ""EntityWithOneProperty"")
+ .WithOne(""EntityWithTwoProperties"")
.HasForeignKey(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithTwoProperties"", ""AlternateId"")
.HasConstraintName(""Constraint"")
.HasAnnotation(""AnnotationName"", ""AnnotationValue"")
@@ -1580,6 +1689,7 @@ public void Do_not_generate_entity_type_builder_again_if_no_foreign_key_is_defin
builder =>
{
builder.Entity();
+ builder.Ignore();
builder.Entity();
},
@"
@@ -1617,7 +1727,7 @@ public void Do_not_generate_entity_type_builder_again_if_no_foreign_key_is_defin
builder.Entity(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+BaseType"", b =>
{
- b.HasOne(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithOneProperty"")
+ b.HasOne(""Microsoft.EntityFrameworkCore.Commands.Migrations.ModelSnapshotTest+EntityWithOneProperty"", ""Navigation"")
.WithMany()
.HasForeignKey(""NavigationId"");
});
diff --git a/test/Microsoft.EntityFrameworkCore.Tests/Metadata/Internal/EntityTypeTest.cs b/test/Microsoft.EntityFrameworkCore.Tests/Metadata/Internal/EntityTypeTest.cs
index b9c4cc9e3fe..2e414cd1061 100644
--- a/test/Microsoft.EntityFrameworkCore.Tests/Metadata/Internal/EntityTypeTest.cs
+++ b/test/Microsoft.EntityFrameworkCore.Tests/Metadata/Internal/EntityTypeTest.cs
@@ -1972,7 +1972,7 @@ public void Adding_a_new_navigation_with_a_name_that_conflicts_with_a_property_t
}
[Fact]
- public void Adding_a_navigation_to_a_shadow_entity_type_throws()
+ public void Can_add_a_navigation_to_shadow_entity()
{
var model = new Model();
var customerType = model.AddEntityType(typeof(Customer));
@@ -1982,14 +1982,11 @@ public void Adding_a_navigation_to_a_shadow_entity_type_throws()
var foreignKeyProperty = orderType.AddProperty("CustomerId", typeof(int));
var customerForeignKey = orderType.GetOrAddForeignKey(foreignKeyProperty, customerKey, customerType);
- Assert.Equal(
- CoreStrings.NavigationOnShadowEntity("Customer", "Order"),
- Assert.Throws(
- () => customerForeignKey.HasDependentToPrincipal("Customer")).Message);
+ Assert.NotNull(customerForeignKey.HasDependentToPrincipal("Customer"));
}
[Fact]
- public void Adding_a_navigation_pointing_to_a_shadow_entity_type_throws()
+ public void Adding_a_navigation_on_non_shadow_entity_type_pointing_to_a_shadow_entity_type_throws()
{
var model = new Model();
var customerType = model.AddEntityType("Customer");
@@ -2005,6 +2002,23 @@ public void Adding_a_navigation_pointing_to_a_shadow_entity_type_throws()
() => customerForeignKey.HasDependentToPrincipal("Customer")).Message);
}
+ [Fact]
+ public void Adding_a_shadow_navigation_on_a_non_shadow_entity_type_throws()
+ {
+ var model = new Model();
+ var customerType = model.AddEntityType(typeof(Customer));
+ var customerKey = customerType.GetOrAddKey(customerType.AddProperty("Id", typeof(int)));
+
+ var orderType = model.AddEntityType(typeof(Order));
+ var foreignKeyProperty = orderType.AddProperty("CustomerId", typeof(int));
+ var customerForeignKey = orderType.GetOrAddForeignKey(foreignKeyProperty, customerKey, customerType);
+
+ Assert.Equal(
+ CoreStrings.NoClrNavigation("Navigation", typeof(Order).Name),
+ Assert.Throws(
+ () => customerForeignKey.HasDependentToPrincipal("Navigation")).Message);
+ }
+
[Fact]
public void Adding_a_navigation_that_doesnt_match_a_CLR_property_throws()
{
diff --git a/test/Microsoft.EntityFrameworkCore.Tests/ModelBuilderTest/ModelBuilderNonGenericStringTest.cs b/test/Microsoft.EntityFrameworkCore.Tests/ModelBuilderTest/ModelBuilderNonGenericStringTest.cs
index 9edded211f9..50a6bc1d3f9 100644
--- a/test/Microsoft.EntityFrameworkCore.Tests/ModelBuilderTest/ModelBuilderNonGenericStringTest.cs
+++ b/test/Microsoft.EntityFrameworkCore.Tests/ModelBuilderTest/ModelBuilderNonGenericStringTest.cs
@@ -6,6 +6,7 @@
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore.Internal;
+using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Xunit;
@@ -15,18 +16,141 @@ namespace Microsoft.EntityFrameworkCore.Tests
{
public class ModelBuilderNonGenericStringTest : ModelBuilderNonGenericTest
{
- public class NonGenericOneToManyType : OneToManyTestBase
+ public class NonGenericStringOneToManyType : OneToManyTestBase
{
+ [Fact]
+ public virtual void Can_create_shadow_navigations_between_shadow_entity_types()
+ {
+ var modelBuilder = (NonGenericStringTestModelBuilder)CreateModelBuilder();
+ var foreignKey = modelBuilder.Entity("Order")
+ .HasOne("Customer", "Customer")
+ .WithMany("Orders")
+ .Metadata;
+
+ Assert.Equal("Customer", modelBuilder.Model.FindEntityType("Order")?.GetNavigations().Single().Name);
+ Assert.Equal("Orders", modelBuilder.Model.FindEntityType("Customer")?.GetNavigations().Single().Name);
+ Assert.False(foreignKey.IsUnique);
+
+ // TODO: Issue#4016 - The Exception message here should be about shadow entity type instead of shadow key.
+ Assert.Equal(
+ CoreStrings.ReferencedShadowKey("{'TempId'}", "Customer.Orders", "Order.Customer"),
+ Assert.Throws(() => modelBuilder.Validate()).Message);
+ }
+
+ [Fact]
+ public virtual void Cannot_create_navigation_on_non_shadow_entity_targeting_shadow_entity()
+ {
+ var modelBuilder = (NonGenericStringTestModelBuilder)CreateModelBuilder();
+ var orderEntityType = modelBuilder.Entity(typeof(Order));
+
+ Assert.Equal(
+ CoreStrings.NavigationToShadowEntity("Customer", typeof(Order).DisplayName(fullName: false), "Customer"),
+ Assert.Throws(() => orderEntityType.HasOne("Customer", "Customer")).Message);
+ }
+
+ [Fact]
+ public virtual void Cannot_create_shadow_navigation_between_non_shadow_entity_types()
+ {
+ var modelBuilder = (NonGenericStringTestModelBuilder)CreateModelBuilder();
+ var orderEntityType = modelBuilder.Entity(typeof(Order));
+
+ Assert.Equal(
+ CoreStrings.NoClrNavigation("CustomerNavigation", typeof(Order).DisplayName(fullName: false)),
+ Assert.Throws(() => orderEntityType.HasOne(typeof(Customer), "CustomerNavigation")).Message);
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(ModelBuilder modelBuilder) => new NonGenericStringTestModelBuilder(modelBuilder);
}
- public class NonGenericManyToOneType : ManyToOneTestBase
+ public class NonGenericStringManyToOneType : ManyToOneTestBase
{
+ [Fact]
+ public virtual void Can_create_shadow_navigations_between_shadow_entity_types()
+ {
+ var modelBuilder = (NonGenericStringTestModelBuilder)CreateModelBuilder();
+ var foreignKey = modelBuilder.Entity("Customer")
+ .HasMany("Order", "Orders")
+ .WithOne("Customer")
+ .Metadata;
+
+ Assert.Equal("Customer", modelBuilder.Model.FindEntityType("Order")?.GetNavigations().Single().Name);
+ Assert.Equal("Orders", modelBuilder.Model.FindEntityType("Customer")?.GetNavigations().Single().Name);
+ Assert.False(foreignKey.IsUnique);
+
+ // TODO: Issue#4016 - The Exception message here should be about shadow entity type instead of shadow key.
+ Assert.Equal(
+ CoreStrings.ReferencedShadowKey("{'TempId'}", "Customer.Orders", "Order.Customer"),
+ Assert.Throws(() => modelBuilder.Validate()).Message);
+ }
+
+ [Fact]
+ public virtual void Cannot_create_navigation_on_non_shadow_entity_targeting_shadow_entity()
+ {
+ var modelBuilder = (NonGenericStringTestModelBuilder)CreateModelBuilder();
+ var customerEntityType = modelBuilder.Entity(typeof(Customer));
+
+ Assert.Equal(
+ CoreStrings.NavigationToShadowEntity("Orders", typeof(Customer).DisplayName(fullName: false), "Order"),
+ Assert.Throws(() => customerEntityType.HasMany("Order", "Orders")).Message);
+ }
+
+ [Fact]
+ public virtual void Cannot_create_shadow_navigation_between_non_shadow_entity_types()
+ {
+ var modelBuilder = (NonGenericStringTestModelBuilder)CreateModelBuilder();
+ var customerEntityType = modelBuilder.Entity(typeof(Customer));
+
+ Assert.Equal(
+ CoreStrings.NoClrNavigation("OrdersNavigation", typeof(Customer).DisplayName(fullName: false)),
+ Assert.Throws(() => customerEntityType.HasMany(typeof(Order), "OrdersNavigation")).Message);
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(ModelBuilder modelBuilder) => new NonGenericStringTestModelBuilder(modelBuilder);
}
- public class NonGenericOneToOneType : OneToOneTestBase
+ public class NonGenericStringOneToOneType : OneToOneTestBase
{
+ [Fact]
+ public virtual void Can_create_shadow_navigations_between_shadow_entity_types()
+ {
+ var modelBuilder = (NonGenericStringTestModelBuilder)CreateModelBuilder();
+ var foreignKey = modelBuilder.Entity("Order")
+ .HasOne("OrderDetails", "OrderDetails")
+ .WithOne("Order")
+ .Metadata;
+
+ Assert.Equal("OrderDetails", modelBuilder.Model.FindEntityType("Order")?.GetNavigations().Single().Name);
+ Assert.Equal("Order", modelBuilder.Model.FindEntityType("OrderDetails")?.GetNavigations().Single().Name);
+ Assert.True(foreignKey.IsUnique);
+
+ // TODO: Issue#4016 - The Exception message here should be about shadow entity type instead of shadow key.
+ Assert.Equal(
+ CoreStrings.ReferencedShadowKey("{'TempId'}", "OrderDetails.Order", "Order.OrderDetails"),
+ Assert.Throws(() => modelBuilder.Validate()).Message);
+ }
+
+ [Fact]
+ public virtual void Cannot_create_navigation_on_non_shadow_entity_targeting_shadow_entity()
+ {
+ var modelBuilder = (NonGenericStringTestModelBuilder)CreateModelBuilder();
+ var orderEntityType = modelBuilder.Entity(typeof(Order));
+
+ Assert.Equal(
+ CoreStrings.NavigationToShadowEntity("OrderDetails", typeof(Order).DisplayName(fullName: false), "OrderDetails"),
+ Assert.Throws(() => orderEntityType.HasOne("OrderDetails", "OrderDetails")).Message);
+ }
+
+ [Fact]
+ public virtual void Cannot_create_shadow_navigation_between_non_shadow_entity_types()
+ {
+ var modelBuilder = (NonGenericStringTestModelBuilder)CreateModelBuilder();
+ var orderEntityType = modelBuilder.Entity(typeof(Order));
+
+ Assert.Equal(
+ CoreStrings.NoClrNavigation("OrderDetailsNavigation", typeof(Order).DisplayName(fullName: false)),
+ Assert.Throws(() => orderEntityType.HasOne(typeof(OrderDetails), "OrderDetailsNavigation")).Message);
+ }
+
protected override TestModelBuilder CreateTestModelBuilder(ModelBuilder modelBuilder) => new NonGenericStringTestModelBuilder(modelBuilder);
}
@@ -40,6 +164,12 @@ public NonGenericStringTestModelBuilder(ModelBuilder modelBuilder)
public override TestEntityTypeBuilder Entity()
=> new NonGenericStringTestEntityTypeBuilder(ModelBuilder.Entity(typeof(TEntity)));
+ public NonGenericStringTestEntityTypeBuilder Entity(Type type)
+ => new NonGenericStringTestEntityTypeBuilder(ModelBuilder.Entity(type));
+
+ public NonGenericStringTestEntityTypeBuilder Entity(string name)
+ => new NonGenericStringTestEntityTypeBuilder(ModelBuilder.Entity(name));
+
public override TestModelBuilder Entity(Action> buildAction)
=> new NonGenericStringTestModelBuilder(ModelBuilder.Entity(typeof(TEntity), entityTypeBuilder =>
buildAction(new NonGenericStringTestEntityTypeBuilder(entityTypeBuilder))));
@@ -69,6 +199,28 @@ public override TestCollectionNavigationBuilder HasMany
=> new NonGenericTestCollectionNavigationBuilder(EntityTypeBuilder.HasMany(typeof(TRelatedEntity).FullName, collection?.GetPropertyAccess().Name));
}
+ private class NonGenericStringTestEntityTypeBuilder
+ {
+ public NonGenericStringTestEntityTypeBuilder(EntityTypeBuilder entityTypeBuilder)
+ {
+ EntityTypeBuilder = entityTypeBuilder;
+ }
+
+ private EntityTypeBuilder EntityTypeBuilder { get; }
+
+ public NonGenericStringTestReferenceNavigationBuilder HasOne(string relatedTypeName, string navigationName)
+ => new NonGenericStringTestReferenceNavigationBuilder(EntityTypeBuilder.HasOne(relatedTypeName, navigationName));
+
+ public NonGenericStringTestCollectionNavigationBuilder HasMany(string relatedTypeName, string navigationName)
+ => new NonGenericStringTestCollectionNavigationBuilder(EntityTypeBuilder.HasMany(relatedTypeName, navigationName));
+
+ public NonGenericStringTestReferenceNavigationBuilder HasOne(Type relatedType, string navigationName)
+ => new NonGenericStringTestReferenceNavigationBuilder(EntityTypeBuilder.HasOne(relatedType, navigationName));
+
+ public NonGenericStringTestCollectionNavigationBuilder HasMany(Type relatedType, string navigationName)
+ => new NonGenericStringTestCollectionNavigationBuilder(EntityTypeBuilder.HasMany(relatedType, navigationName));
+ }
+
private class NonGenericStringTestReferenceNavigationBuilder : NonGenericTestReferenceNavigationBuilder
where TEntity : class
where TRelatedEntity : class
@@ -85,6 +237,35 @@ public override TestReferenceReferenceBuilder WithOne(E
}
}
+ private class NonGenericStringTestReferenceNavigationBuilder
+ {
+ public NonGenericStringTestReferenceNavigationBuilder(ReferenceNavigationBuilder referenceNavigationBuilder)
+ {
+ ReferenceNavigationBuilder = referenceNavigationBuilder;
+ }
+
+ private ReferenceNavigationBuilder ReferenceNavigationBuilder { get; }
+
+ public NonGenericStringTestReferenceCollectionBuilder WithMany(string collection = null)
+ => new NonGenericStringTestReferenceCollectionBuilder(ReferenceNavigationBuilder.WithMany(collection));
+
+ public NonGenericStringTestReferenceReferenceBuilder WithOne(string reference = null)
+ => new NonGenericStringTestReferenceReferenceBuilder(ReferenceNavigationBuilder.WithOne(reference));
+ }
+
+ private class NonGenericStringTestCollectionNavigationBuilder
+ {
+ public NonGenericStringTestCollectionNavigationBuilder(CollectionNavigationBuilder collectionNavigationBuilder)
+ {
+ CollectionNavigationBuilder = collectionNavigationBuilder;
+ }
+
+ private CollectionNavigationBuilder CollectionNavigationBuilder { get; }
+
+ public NonGenericStringTestReferenceCollectionBuilder WithOne(string reference = null)
+ => new NonGenericStringTestReferenceCollectionBuilder(CollectionNavigationBuilder.WithOne(reference));
+ }
+
private class NonGenericStringTestReferenceReferenceBuilder : NonGenericTestReferenceReferenceBuilder
where TEntity : class
where TRelatedEntity : class
@@ -103,5 +284,27 @@ public override TestReferenceReferenceBuilder HasForeig
public override TestReferenceReferenceBuilder HasPrincipalKey(Expression> keyExpression)
=> Wrap(ReferenceReferenceBuilder.HasPrincipalKey(typeof(TPrincipalEntity).FullName, keyExpression.GetPropertyAccessList().Select(p => p.Name).ToArray()));
}
+
+ private class NonGenericStringTestReferenceReferenceBuilder
+ {
+ public NonGenericStringTestReferenceReferenceBuilder(ReferenceReferenceBuilder referenceReferenceBuilder)
+ {
+ ReferenceReferenceBuilder = referenceReferenceBuilder;
+ }
+
+ private ReferenceReferenceBuilder ReferenceReferenceBuilder { get; }
+ public IMutableForeignKey Metadata => ReferenceReferenceBuilder.Metadata;
+ }
+
+ private class NonGenericStringTestReferenceCollectionBuilder
+ {
+ public NonGenericStringTestReferenceCollectionBuilder(ReferenceCollectionBuilder referenceCollectionBuilder)
+ {
+ ReferenceCollectionBuilder = referenceCollectionBuilder;
+ }
+
+ private ReferenceCollectionBuilder ReferenceCollectionBuilder { get; }
+ public IMutableForeignKey Metadata => ReferenceCollectionBuilder.Metadata;
+ }
}
}