diff --git a/src/EFCore.Relational/Diagnostics/IndexInvalidPropertiesEventData.cs b/src/EFCore.Relational/Diagnostics/IndexWithPropertiesEventData.cs
similarity index 97%
rename from src/EFCore.Relational/Diagnostics/IndexInvalidPropertiesEventData.cs
rename to src/EFCore.Relational/Diagnostics/IndexWithPropertiesEventData.cs
index f55a60f5fc9..686ce11ba98 100644
--- a/src/EFCore.Relational/Diagnostics/IndexInvalidPropertiesEventData.cs
+++ b/src/EFCore.Relational/Diagnostics/IndexWithPropertiesEventData.cs
@@ -13,7 +13,7 @@ namespace Microsoft.EntityFrameworkCore.Diagnostics
/// A event payload class for the
/// event.
///
- public class IndexInvalidPropertiesEventData : EventData
+ public class IndexWithPropertiesEventData : EventData
{
///
/// Constructs the event payload for the event.
@@ -27,7 +27,7 @@ public class IndexInvalidPropertiesEventData : EventData
/// The tables mapped to the first property.
/// The name of the second property name which causes this event.
/// The tables mapped to the second property.
- public IndexInvalidPropertiesEventData(
+ public IndexWithPropertiesEventData(
[NotNull] EventDefinitionBase eventDefinition,
[NotNull] Func messageGenerator,
[NotNull] IEntityType entityType,
diff --git a/src/EFCore.Relational/Diagnostics/IndexInvalidPropertyEventData.cs b/src/EFCore.Relational/Diagnostics/IndexWithPropertyEventData.cs
similarity index 89%
rename from src/EFCore.Relational/Diagnostics/IndexInvalidPropertyEventData.cs
rename to src/EFCore.Relational/Diagnostics/IndexWithPropertyEventData.cs
index cbaaf9d87b6..82c33c189e4 100644
--- a/src/EFCore.Relational/Diagnostics/IndexInvalidPropertyEventData.cs
+++ b/src/EFCore.Relational/Diagnostics/IndexWithPropertyEventData.cs
@@ -13,7 +13,7 @@ namespace Microsoft.EntityFrameworkCore.Diagnostics
/// A event payload class for
/// the events involving an invalid property name on an index.
///
- public class IndexInvalidPropertyEventData : EventData
+ public class IndexWithPropertyEventData : EventData
{
///
/// Constructs the event payload for indexes with a invalid property.
@@ -24,7 +24,7 @@ public class IndexInvalidPropertyEventData : EventData
/// The name of the index.
/// The names of the properties which define the index.
/// The property name which is invalid.
- public IndexInvalidPropertyEventData(
+ public IndexWithPropertyEventData(
[NotNull] EventDefinitionBase eventDefinition,
[NotNull] Func messageGenerator,
[NotNull] IEntityType entityType,
@@ -36,7 +36,7 @@ public IndexInvalidPropertyEventData(
EntityType = entityType;
Name = indexName;
PropertyNames = indexPropertyNames;
- InvalidPropertyName = invalidPropertyName;
+ PropertyName = invalidPropertyName;
}
///
@@ -55,8 +55,8 @@ public IndexInvalidPropertyEventData(
public virtual List PropertyNames { get; }
///
- /// The name of the invalid property.
+ /// The name of the specific property.
///
- public virtual string InvalidPropertyName { get; }
+ public virtual string PropertyName { get; }
}
}
diff --git a/src/EFCore.Relational/Diagnostics/RelationalEventId.cs b/src/EFCore.Relational/Diagnostics/RelationalEventId.cs
index 8425d1c7c08..45f08af32ac 100644
--- a/src/EFCore.Relational/Diagnostics/RelationalEventId.cs
+++ b/src/EFCore.Relational/Diagnostics/RelationalEventId.cs
@@ -674,7 +674,7 @@ private enum Id
/// This event is in the category.
///
///
- /// This event uses the payload when used with a .
+ /// This event uses the payload when used with a .
///
///
public static readonly EventId IndexPropertiesBothMappedAndNotMappedToTable = MakeValidationId(Id.IndexPropertiesBothMappedAndNotMappedToTable);
@@ -687,7 +687,7 @@ private enum Id
/// This event is in the category.
///
///
- /// This event uses the payload when used with a .
+ /// This event uses the payload when used with a .
///
///
public static readonly EventId IndexPropertiesMappedToNonOverlappingTables = MakeValidationId(Id.IndexPropertiesMappedToNonOverlappingTables);
diff --git a/src/EFCore.Relational/Diagnostics/RelationalLoggerExtensions.cs b/src/EFCore.Relational/Diagnostics/RelationalLoggerExtensions.cs
index 6bf3eb1fcbd..a12646bc319 100644
--- a/src/EFCore.Relational/Diagnostics/RelationalLoggerExtensions.cs
+++ b/src/EFCore.Relational/Diagnostics/RelationalLoggerExtensions.cs
@@ -4460,7 +4460,7 @@ public static void IndexPropertiesBothMappedAndNotMappedToTable(
if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled))
{
- var eventData = new IndexInvalidPropertyEventData(
+ var eventData = new IndexWithPropertyEventData(
definition,
UnnamedIndexPropertiesBothMappedAndNotMappedToTable,
entityType,
@@ -4486,7 +4486,7 @@ public static void IndexPropertiesBothMappedAndNotMappedToTable(
if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled))
{
- var eventData = new IndexInvalidPropertyEventData(
+ var eventData = new IndexWithPropertyEventData(
definition,
NamedIndexPropertiesBothMappedAndNotMappedToTable,
entityType,
@@ -4502,22 +4502,22 @@ public static void IndexPropertiesBothMappedAndNotMappedToTable(
private static string UnnamedIndexPropertiesBothMappedAndNotMappedToTable(EventDefinitionBase definition, EventData payload)
{
var d = (EventDefinition)definition;
- var p = (IndexInvalidPropertyEventData)payload;
+ var p = (IndexWithPropertyEventData)payload;
return d.GenerateMessage(
p.EntityType.DisplayName(),
p.PropertyNames.Format(),
- p.InvalidPropertyName);
+ p.PropertyName);
}
private static string NamedIndexPropertiesBothMappedAndNotMappedToTable(EventDefinitionBase definition, EventData payload)
{
var d = (EventDefinition)definition;
- var p = (IndexInvalidPropertyEventData)payload;
+ var p = (IndexWithPropertyEventData)payload;
return d.GenerateMessage(
p.Name,
p.EntityType.DisplayName(),
p.PropertyNames.Format(),
- p.InvalidPropertyName);
+ p.PropertyName);
}
///
@@ -4556,7 +4556,7 @@ public static void IndexPropertiesMappedToNonOverlappingTables(
if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled))
{
- var eventData = new IndexInvalidPropertiesEventData(
+ var eventData = new IndexWithPropertiesEventData(
definition,
UnnamedIndexPropertiesMappedToNonOverlappingTables,
entityType,
@@ -4592,7 +4592,7 @@ public static void IndexPropertiesMappedToNonOverlappingTables(
if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled))
{
- var eventData = new IndexInvalidPropertiesEventData(
+ var eventData = new IndexWithPropertiesEventData(
definition,
NamedIndexPropertiesMappedToNonOverlappingTables,
entityType,
@@ -4611,7 +4611,7 @@ public static void IndexPropertiesMappedToNonOverlappingTables(
private static string UnnamedIndexPropertiesMappedToNonOverlappingTables(EventDefinitionBase definition, EventData payload)
{
var d = (EventDefinition)definition;
- var p = (IndexInvalidPropertiesEventData)payload;
+ var p = (IndexWithPropertiesEventData)payload;
return d.GenerateMessage(
p.EntityType.DisplayName(),
p.PropertyNames.Format(),
@@ -4624,7 +4624,7 @@ private static string UnnamedIndexPropertiesMappedToNonOverlappingTables(EventDe
private static string NamedIndexPropertiesMappedToNonOverlappingTables(EventDefinitionBase definition, EventData payload)
{
var d = (FallbackEventDefinition)definition;
- var p = (IndexInvalidPropertiesEventData)payload;
+ var p = (IndexWithPropertiesEventData)payload;
return d.GenerateMessage(
l => l.Log(
d.Level,
diff --git a/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs b/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs
index 84138bfc529..ba82da0fa4e 100644
--- a/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs
+++ b/src/EFCore.Relational/Extensions/RelationalEntityTypeExtensions.cs
@@ -766,7 +766,7 @@ public static IEnumerable FindRowInternalForeignKeys(
/// The entity type.
/// The identifier of the store object.
public static IEnumerable FindRowInternalForeignKeys(
- [NotNull] this IMutableEntityType entityType, StoreObjectIdentifier storeObject)
+ [NotNull] this IMutableEntityType entityType, in StoreObjectIdentifier storeObject)
=> ((IEntityType)entityType).FindRowInternalForeignKeys(storeObject).Cast();
///
@@ -776,7 +776,7 @@ public static IEnumerable FindRowInternalForeignKeys(
/// The entity type.
/// The identifier of the store object.
public static IEnumerable FindRowInternalForeignKeys(
- [NotNull] this IConventionEntityType entityType, StoreObjectIdentifier storeObject)
+ [NotNull] this IConventionEntityType entityType, in StoreObjectIdentifier storeObject)
=> ((IEntityType)entityType).FindRowInternalForeignKeys(storeObject).Cast();
///
diff --git a/src/EFCore.Relational/Extensions/RelationalForeignKeyExtensions.cs b/src/EFCore.Relational/Extensions/RelationalForeignKeyExtensions.cs
index 453bde9b57e..aa1f64fc255 100644
--- a/src/EFCore.Relational/Extensions/RelationalForeignKeyExtensions.cs
+++ b/src/EFCore.Relational/Extensions/RelationalForeignKeyExtensions.cs
@@ -35,7 +35,7 @@ public static string GetConstraintName([NotNull] this IForeignKey foreignKey)
/// The identifier of the principal store object.
/// The foreign key constraint name.
public static string GetConstraintName(
- [NotNull] this IForeignKey foreignKey, StoreObjectIdentifier storeObject, StoreObjectIdentifier principalStoreObject)
+ [NotNull] this IForeignKey foreignKey, in StoreObjectIdentifier storeObject, in StoreObjectIdentifier principalStoreObject)
{
var annotation = foreignKey.FindAnnotation(RelationalAnnotationNames.Name);
return annotation != null
@@ -75,24 +75,32 @@ public static string GetDefaultName([NotNull] this IForeignKey foreignKey)
/// The default constraint name that would be used for this foreign key.
public static string GetDefaultName(
[NotNull] this IForeignKey foreignKey,
- StoreObjectIdentifier storeObject,
- StoreObjectIdentifier principalStoreObject)
+ in StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier principalStoreObject)
{
- var propertyNames = foreignKey.Properties.Select(p => p.GetColumnName(storeObject)).ToList();
- var principalPropertyNames = foreignKey.PrincipalKey.Properties.Select(p => p.GetColumnName(storeObject)).ToList();
+ var propertyNames = foreignKey.Properties.GetColumnNames(storeObject);
+ var principalPropertyNames = foreignKey.PrincipalKey.Properties.GetColumnNames(principalStoreObject);
var rootForeignKey = foreignKey;
// Limit traversal to avoid getting stuck in a cycle (validation will throw for these later)
// Using a hashset is detrimental to the perf when there are no cycles
for (var i = 0; i < Metadata.Internal.RelationalEntityTypeExtensions.MaxEntityTypesSharingTable; i++)
{
- var linkedForeignKey = rootForeignKey.DeclaringEntityType
- .FindRowInternalForeignKeys(storeObject)
- .SelectMany(fk => fk.PrincipalEntityType.GetForeignKeys())
- .FirstOrDefault(k => principalStoreObject.Name == k.PrincipalEntityType.GetTableName()
- && principalStoreObject.Schema == k.PrincipalEntityType.GetSchema()
- && propertyNames.SequenceEqual(k.Properties.Select(p => p.GetColumnName(storeObject)))
- && principalPropertyNames.SequenceEqual(k.PrincipalKey.Properties.Select(p => p.GetColumnName(storeObject))));
+ IForeignKey linkedForeignKey = null;
+ foreach (var otherForeignKey in rootForeignKey.DeclaringEntityType
+ .FindRowInternalForeignKeys(storeObject)
+ .SelectMany(fk => fk.PrincipalEntityType.GetForeignKeys()))
+ {
+ if (principalStoreObject.Name == otherForeignKey.PrincipalEntityType.GetTableName()
+ && principalStoreObject.Schema == otherForeignKey.PrincipalEntityType.GetSchema()
+ && propertyNames.SequenceEqual(otherForeignKey.Properties.GetColumnNames(storeObject))
+ && principalPropertyNames.SequenceEqual(otherForeignKey.PrincipalKey.Properties.GetColumnNames(principalStoreObject)))
+ {
+ linkedForeignKey = otherForeignKey;
+ break;
+ }
+ }
+
if (linkedForeignKey == null)
{
break;
@@ -112,7 +120,7 @@ public static string GetDefaultName(
.Append("_")
.Append(principalStoreObject.Name)
.Append("_")
- .AppendJoin(foreignKey.Properties.Select(p => p.GetColumnName(storeObject)), "_")
+ .AppendJoin(propertyNames, "_")
.ToString();
return Uniquifier.Truncate(baseName, foreignKey.DeclaringEntityType.Model.GetMaxIdentifierLength());
@@ -176,7 +184,7 @@ public static IEnumerable GetMappedConstraints([NotNull]
/// The foreign key.
/// The identifier of the containing store object.
/// The foreign key if found, or if none was found.
- public static IForeignKey FindSharedObjectRootForeignKey([NotNull] this IForeignKey foreignKey, StoreObjectIdentifier storeObject)
+ public static IForeignKey FindSharedObjectRootForeignKey([NotNull] this IForeignKey foreignKey, in StoreObjectIdentifier storeObject)
{
Check.NotNull(foreignKey, nameof(foreignKey));
@@ -188,12 +196,22 @@ public static IForeignKey FindSharedObjectRootForeignKey([NotNull] this IForeign
// Using a hashset is detrimental to the perf when there are no cycles
for (var i = 0; i < Metadata.Internal.RelationalEntityTypeExtensions.MaxEntityTypesSharingTable; i++)
{
- var linkedKey = rootForeignKey.DeclaringEntityType
+ IForeignKey linkedKey = null;
+ foreach (var otherForeignKey in rootForeignKey.DeclaringEntityType
.FindRowInternalForeignKeys(storeObject)
- .SelectMany(fk => fk.PrincipalEntityType.GetForeignKeys())
- .FirstOrDefault(k => k.GetConstraintName(storeObject,
- StoreObjectIdentifier.Table(k.PrincipalEntityType.GetTableName(), k.PrincipalEntityType.GetSchema()))
- == foreignKeyName);
+ .SelectMany(fk => fk.PrincipalEntityType.GetForeignKeys()))
+ {
+ if (otherForeignKey.GetConstraintName(storeObject,
+ StoreObjectIdentifier.Table(
+ otherForeignKey.PrincipalEntityType.GetTableName(),
+ otherForeignKey.PrincipalEntityType.GetSchema()))
+ == foreignKeyName)
+ {
+ linkedKey = otherForeignKey;
+ break;
+ }
+ }
+
if (linkedKey == null)
{
break;
@@ -218,7 +236,7 @@ public static IForeignKey FindSharedObjectRootForeignKey([NotNull] this IForeign
/// The identifier of the containing store object.
/// The foreign key if found, or if none was found.
public static IMutableForeignKey FindSharedObjectRootForeignKey(
- [NotNull] this IMutableForeignKey foreignKey, StoreObjectIdentifier storeObject)
+ [NotNull] this IMutableForeignKey foreignKey, in StoreObjectIdentifier storeObject)
=> (IMutableForeignKey)((IForeignKey)foreignKey).FindSharedObjectRootForeignKey(storeObject);
///
@@ -234,7 +252,7 @@ public static IMutableForeignKey FindSharedObjectRootForeignKey(
/// The identifier of the containing store object.
/// The foreign key if found, or if none was found.
public static IConventionForeignKey FindSharedObjectRootForeignKey(
- [NotNull] this IConventionForeignKey foreignKey, StoreObjectIdentifier storeObject)
+ [NotNull] this IConventionForeignKey foreignKey, in StoreObjectIdentifier storeObject)
=> (IConventionForeignKey)((IForeignKey)foreignKey).FindSharedObjectRootForeignKey(storeObject);
}
}
diff --git a/src/EFCore.Relational/Extensions/RelationalIndexExtensions.cs b/src/EFCore.Relational/Extensions/RelationalIndexExtensions.cs
index 5b5c3ae3973..d1c11846955 100644
--- a/src/EFCore.Relational/Extensions/RelationalIndexExtensions.cs
+++ b/src/EFCore.Relational/Extensions/RelationalIndexExtensions.cs
@@ -43,7 +43,7 @@ public static string GetName([NotNull] this IIndex index)
/// The index.
/// The identifier of the store object.
/// The name of the index in the database.
- public static string GetDatabaseName([NotNull] this IIndex index, StoreObjectIdentifier storeObject)
+ public static string GetDatabaseName([NotNull] this IIndex index, in StoreObjectIdentifier storeObject)
=> (string)index[RelationalAnnotationNames.Name]
?? index.Name
?? index.GetDefaultDatabaseName(storeObject);
@@ -82,19 +82,27 @@ public static string GetDefaultName([NotNull] this IIndex index)
/// The index.
/// The identifier of the store object.
/// The default name that would be used for this index.
- public static string GetDefaultDatabaseName([NotNull] this IIndex index, StoreObjectIdentifier storeObject)
+ public static string GetDefaultDatabaseName([NotNull] this IIndex index, in StoreObjectIdentifier storeObject)
{
- var propertyNames = index.Properties.Select(p => p.GetColumnName(storeObject)).ToList();
+ var propertyNames = index.Properties.GetColumnNames(storeObject);
var rootIndex = index;
// Limit traversal to avoid getting stuck in a cycle (validation will throw for these later)
// Using a hashset is detrimental to the perf when there are no cycles
for (var i = 0; i < Metadata.Internal.RelationalEntityTypeExtensions.MaxEntityTypesSharingTable; i++)
{
- var linkedIndex = rootIndex.DeclaringEntityType
+ IIndex linkedIndex = null;
+ foreach(var otherIndex in rootIndex.DeclaringEntityType
.FindRowInternalForeignKeys(storeObject)
- .SelectMany(fk => fk.PrincipalEntityType.GetIndexes())
- .FirstOrDefault(i => i.Properties.Select(p => p.GetColumnName(storeObject)).SequenceEqual(propertyNames));
+ .SelectMany(fk => fk.PrincipalEntityType.GetIndexes()))
+ {
+ if (otherIndex.Properties.GetColumnNames(storeObject).SequenceEqual(propertyNames))
+ {
+ linkedIndex = otherIndex;
+ break;
+ }
+ }
+
if (linkedIndex == null)
{
break;
@@ -201,7 +209,7 @@ public static string GetFilter([NotNull] this IIndex index)
/// The index.
/// The identifier of the containing store object.
/// The index filter expression.
- public static string GetFilter([NotNull] this IIndex index, StoreObjectIdentifier storeObject)
+ public static string GetFilter([NotNull] this IIndex index, in StoreObjectIdentifier storeObject)
{
var annotation = index.FindAnnotation(RelationalAnnotationNames.Filter);
if (annotation != null)
@@ -269,7 +277,7 @@ public static IEnumerable GetMappedTableIndexes([NotNull] this IInd
/// The index.
/// The identifier of the containing store object.
/// The index found, or if none was found.
- public static IIndex FindSharedObjectRootIndex([NotNull] this IIndex index, StoreObjectIdentifier storeObject)
+ public static IIndex FindSharedObjectRootIndex([NotNull] this IIndex index, in StoreObjectIdentifier storeObject)
{
Check.NotNull(index, nameof(index));
@@ -280,10 +288,18 @@ public static IIndex FindSharedObjectRootIndex([NotNull] this IIndex index, Stor
// Using a hashset is detrimental to the perf when there are no cycles
for (var i = 0; i < Metadata.Internal.RelationalEntityTypeExtensions.MaxEntityTypesSharingTable; i++)
{
- var linkedIndex = rootIndex.DeclaringEntityType
+ IIndex linkedIndex = null;
+ foreach(var otherIndex in rootIndex.DeclaringEntityType
.FindRowInternalForeignKeys(storeObject)
- .SelectMany(fk => fk.PrincipalEntityType.GetIndexes())
- .FirstOrDefault(i => i.GetDatabaseName(storeObject) == indexName);
+ .SelectMany(fk => fk.PrincipalEntityType.GetIndexes()))
+ {
+ if (otherIndex.GetDatabaseName(storeObject) == indexName)
+ {
+ linkedIndex = otherIndex;
+ break;
+ }
+ }
+
if (linkedIndex == null)
{
break;
@@ -308,7 +324,7 @@ public static IIndex FindSharedObjectRootIndex([NotNull] this IIndex index, Stor
/// The identifier of the containing store object.
/// The index found, or if none was found.
public static IMutableIndex FindSharedObjectRootIndex(
- [NotNull] this IMutableIndex index, StoreObjectIdentifier storeObject)
+ [NotNull] this IMutableIndex index, in StoreObjectIdentifier storeObject)
=> (IMutableIndex)((IIndex)index).FindSharedObjectRootIndex(storeObject);
///
@@ -324,7 +340,7 @@ public static IMutableIndex FindSharedObjectRootIndex(
/// The identifier of the containing store object.
/// The index found, or if none was found.
public static IConventionIndex FindSharedObjectRootIndex(
- [NotNull] this IConventionIndex index, StoreObjectIdentifier storeObject)
+ [NotNull] this IConventionIndex index, in StoreObjectIdentifier storeObject)
=> (IConventionIndex)((IIndex)index).FindSharedObjectRootIndex(storeObject);
}
}
diff --git a/src/EFCore.Relational/Extensions/RelationalKeyExtensions.cs b/src/EFCore.Relational/Extensions/RelationalKeyExtensions.cs
index c7813ff408f..a51120de937 100644
--- a/src/EFCore.Relational/Extensions/RelationalKeyExtensions.cs
+++ b/src/EFCore.Relational/Extensions/RelationalKeyExtensions.cs
@@ -31,7 +31,7 @@ public static string GetName([NotNull] this IKey key)
/// The key.
/// The identifier of the containing store object.
/// The key constraint name for this key.
- public static string GetName([NotNull] this IKey key, StoreObjectIdentifier storeObject)
+ public static string GetName([NotNull] this IKey key, in StoreObjectIdentifier storeObject)
=> (string)key[RelationalAnnotationNames.Name]
?? key.GetDefaultName(storeObject);
@@ -67,7 +67,7 @@ public static string GetDefaultName([NotNull] this IKey key)
/// The key.
/// The identifier of the containing store object.
/// The default key constraint name that would be used for this key.
- public static string GetDefaultName([NotNull] this IKey key, StoreObjectIdentifier storeObject)
+ public static string GetDefaultName([NotNull] this IKey key, in StoreObjectIdentifier storeObject)
{
string name = null;
if (key.IsPrimaryKey())
@@ -97,17 +97,25 @@ public static string GetDefaultName([NotNull] this IKey key, StoreObjectIdentifi
}
else
{
- var propertyNames = key.Properties.Select(p => p.GetColumnName(storeObject)).ToList();
+ var propertyNames = key.Properties.GetColumnNames(storeObject);
var rootKey = key;
// Limit traversal to avoid getting stuck in a cycle (validation will throw for these later)
// Using a hashset is detrimental to the perf when there are no cycles
for (var i = 0; i < Metadata.Internal.RelationalEntityTypeExtensions.MaxEntityTypesSharingTable; i++)
{
- var linkedKey = rootKey.DeclaringEntityType
+ IKey linkedKey = null;
+ foreach(var otherKey in rootKey.DeclaringEntityType
.FindRowInternalForeignKeys(storeObject)
- .SelectMany(fk => fk.PrincipalEntityType.GetKeys())
- .FirstOrDefault(k => k.Properties.Select(p => p.GetColumnName(storeObject)).SequenceEqual(propertyNames));
+ .SelectMany(fk => fk.PrincipalEntityType.GetKeys()))
+ {
+ if (otherKey.Properties.GetColumnNames(storeObject).SequenceEqual(propertyNames))
+ {
+ linkedKey = otherKey;
+ break;
+ }
+ }
+
if (linkedKey == null)
{
break;
@@ -125,7 +133,7 @@ public static string GetDefaultName([NotNull] this IKey key, StoreObjectIdentifi
.Append("AK_")
.Append(storeObject.Name)
.Append("_")
- .AppendJoin(key.Properties.Select(p => p.GetColumnName(storeObject)), "_")
+ .AppendJoin(propertyNames, "_")
.ToString();
}
@@ -188,7 +196,7 @@ public static IEnumerable GetMappedConstraints([NotNull] this
/// The key.
/// The identifier of the containing store object.
/// The key found, or if none was found.
- public static IKey FindSharedObjectRootKey([NotNull] this IKey key, StoreObjectIdentifier storeObject)
+ public static IKey FindSharedObjectRootKey([NotNull] this IKey key, in StoreObjectIdentifier storeObject)
{
Check.NotNull(key, nameof(key));
@@ -199,10 +207,18 @@ public static IKey FindSharedObjectRootKey([NotNull] this IKey key, StoreObjectI
// Using a hashset is detrimental to the perf when there are no cycles
for (var i = 0; i < Metadata.Internal.RelationalEntityTypeExtensions.MaxEntityTypesSharingTable; i++)
{
- var linkedKey = rootKey.DeclaringEntityType
+ IKey linkedKey = null;
+ foreach (var otherKey in rootKey.DeclaringEntityType
.FindRowInternalForeignKeys(storeObject)
- .SelectMany(fk => fk.PrincipalEntityType.GetKeys())
- .FirstOrDefault(k => k.GetName(storeObject) == keyName);
+ .SelectMany(fk => fk.PrincipalEntityType.GetKeys()))
+ {
+ if (otherKey.GetName(storeObject) == keyName)
+ {
+ linkedKey = otherKey;
+ break;
+ }
+ }
+
if (linkedKey == null)
{
break;
@@ -227,7 +243,7 @@ public static IKey FindSharedObjectRootKey([NotNull] this IKey key, StoreObjectI
/// The identifier of the containing store object.
/// The key found, or if none was found.
public static IMutableKey FindSharedObjectRootKey(
- [NotNull] this IMutableKey key, StoreObjectIdentifier storeObject)
+ [NotNull] this IMutableKey key, in StoreObjectIdentifier storeObject)
=> (IMutableKey)((IKey)key).FindSharedObjectRootKey(storeObject);
///
@@ -243,7 +259,7 @@ public static IMutableKey FindSharedObjectRootKey(
/// The identifier of the containing store object.
/// The key found, or if none was found.
public static IConventionKey FindSharedObjectRootKey(
- [NotNull] this IConventionKey key, StoreObjectIdentifier storeObject)
+ [NotNull] this IConventionKey key, in StoreObjectIdentifier storeObject)
=> (IConventionKey)((IKey)key).FindSharedObjectRootKey(storeObject);
}
}
diff --git a/src/EFCore.Relational/Extensions/RelationalPropertyBuilderExtensions.cs b/src/EFCore.Relational/Extensions/RelationalPropertyBuilderExtensions.cs
index 3f8358e7e17..894ebeed952 100644
--- a/src/EFCore.Relational/Extensions/RelationalPropertyBuilderExtensions.cs
+++ b/src/EFCore.Relational/Extensions/RelationalPropertyBuilderExtensions.cs
@@ -84,7 +84,7 @@ public static IConventionPropertyBuilder HasColumnName(
public static IConventionPropertyBuilder HasColumnName(
[NotNull] this IConventionPropertyBuilder propertyBuilder,
[CanBeNull] string name,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
bool fromDataAnnotation = false)
{
if (!propertyBuilder.CanSetColumnName(name, storeObject, fromDataAnnotation))
@@ -120,7 +120,7 @@ public static bool CanSetColumnName(
public static bool CanSetColumnName(
[NotNull] this IConventionPropertyBuilder propertyBuilder,
[CanBeNull] string name,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
bool fromDataAnnotation = false)
{
var overrides = RelationalPropertyOverrides.Find(propertyBuilder.Metadata, storeObject);
diff --git a/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs b/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs
index 069fa6a2086..4b9ba74e622 100644
--- a/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs
+++ b/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs
@@ -40,7 +40,7 @@ public static string GetColumnName([NotNull] this IProperty property)
/// The property.
/// The identifier of the table-like store object containing the column.
/// The name of the column to which the property is mapped.
- public static string GetColumnName([NotNull] this IProperty property, StoreObjectIdentifier storeObject)
+ public static string GetColumnName([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
{
Check.NotNull(property, nameof(property));
@@ -73,7 +73,7 @@ public static string GetDefaultColumnName([NotNull] this IProperty property)
/// The property.
/// The identifier of the table-like store object containing the column.
/// The default column name to which the property would be mapped.
- public static string GetDefaultColumnName([NotNull] this IProperty property, StoreObjectIdentifier storeObject)
+ public static string GetDefaultColumnName([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
{
var sharedTablePrincipalPrimaryKeyProperty = FindSharedObjectRootPrimaryKeyProperty(property, storeObject);
if (sharedTablePrincipalPrimaryKeyProperty != null)
@@ -188,7 +188,7 @@ public static string SetColumnName(
/// The name to set.
/// The identifier of the table-like store object containing the column.
public static void SetColumnName(
- [NotNull] this IMutableProperty property, [CanBeNull] string name, StoreObjectIdentifier storeObject)
+ [NotNull] this IMutableProperty property, [CanBeNull] string name, in StoreObjectIdentifier storeObject)
=> RelationalPropertyOverrides.GetOrCreate(property, storeObject)
.SetColumnName(name, ConfigurationSource.Explicit);
@@ -203,7 +203,7 @@ public static void SetColumnName(
public static string SetColumnName(
[NotNull] this IConventionProperty property,
[CanBeNull] string name,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
bool fromDataAnnotation = false)
=> RelationalPropertyOverrides.GetOrCreate(property, storeObject)
.SetColumnName(name, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
@@ -224,7 +224,7 @@ public static string SetColumnName(
/// The for the column name for a particular table-like store object.
public static ConfigurationSource? GetColumnNameConfigurationSource(
[NotNull] this IConventionProperty property,
- StoreObjectIdentifier storeObject)
+ in StoreObjectIdentifier storeObject)
=> RelationalPropertyOverrides.Find(property, storeObject)?.GetColumnNameConfigurationSource();
///
@@ -246,7 +246,7 @@ public static string GetColumnType([NotNull] this IProperty property)
/// The property.
/// The identifier of the table-like store object containing the column.
/// The database type of the column to which the property is mapped.
- public static string GetColumnType([NotNull] this IProperty property, StoreObjectIdentifier storeObject)
+ public static string GetColumnType([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(RelationalAnnotationNames.ColumnType);
if (annotation != null)
@@ -257,7 +257,7 @@ public static string GetColumnType([NotNull] this IProperty property, StoreObjec
return GetDefaultColumnType(property, storeObject);
}
- private static string GetDefaultColumnType(IProperty property, StoreObjectIdentifier storeObject)
+ private static string GetDefaultColumnType(IProperty property, in StoreObjectIdentifier storeObject)
{
var sharedTableRootProperty = property.FindSharedStoreObjectRootProperty(storeObject);
return sharedTableRootProperty != null
@@ -352,26 +352,50 @@ public static IEnumerable GetFunctionColumnMappings([Not
/// The property.
/// The identifier of the table-like store object containing the column.
/// The column to which the property is mapped.
- public static IColumnBase FindColumn([NotNull] this IProperty property, StoreObjectIdentifier storeObject)
+ public static IColumnBase FindColumn([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
{
switch (storeObject.StoreObjectType)
{
case StoreObjectType.Table:
- return property.GetTableColumnMappings()
- .Where(m => m.TableMapping.Table.Name == storeObject.Name && m.TableMapping.Table.Schema == storeObject.Schema)
- .FirstOrDefault()?.Column;
+ foreach (var mapping in property.GetTableColumnMappings())
+ {
+ if (mapping.TableMapping.Table.Name == storeObject.Name && mapping.TableMapping.Table.Schema == storeObject.Schema)
+ {
+ return mapping.Column;
+ }
+ }
+
+ return null;
case StoreObjectType.View:
- return property.GetViewColumnMappings()
- .Where(m => m.ViewMapping.Table.Name == storeObject.Name && m.ViewMapping.Table.Schema == storeObject.Schema)
- .FirstOrDefault()?.Column;
+ foreach (var mapping in property.GetViewColumnMappings())
+ {
+ if (mapping.TableMapping.Table.Name == storeObject.Name && mapping.TableMapping.Table.Schema == storeObject.Schema)
+ {
+ return mapping.Column;
+ }
+ }
+
+ return null;
case StoreObjectType.SqlQuery:
- return property.GetSqlQueryColumnMappings()
- .Where(m => m.SqlQueryMapping.SqlQuery.Name == storeObject.Name)
- .FirstOrDefault()?.Column;
+ foreach (var mapping in property.GetSqlQueryColumnMappings())
+ {
+ if (mapping.TableMapping.Table.Name == storeObject.Name)
+ {
+ return mapping.Column;
+ }
+ }
+
+ return null;
case StoreObjectType.Function:
- return property.GetFunctionColumnMappings()
- .Where(m => m.FunctionMapping.DbFunction.Name == storeObject.Name)
- .FirstOrDefault()?.Column;
+ foreach (var mapping in property.GetFunctionColumnMappings())
+ {
+ if (mapping.TableMapping.Table.Name == storeObject.Name)
+ {
+ return mapping.Column;
+ }
+ }
+
+ return null;
default:
throw new NotImplementedException(storeObject.StoreObjectType.ToString());
}
@@ -394,7 +418,7 @@ public static string GetDefaultValueSql([NotNull] this IProperty property)
/// The property.
/// The identifier of the table-like store object containing the column.
/// The SQL expression that is used as the default value for the column this property is mapped to.
- public static string GetDefaultValueSql([NotNull] this IProperty property, StoreObjectIdentifier storeObject)
+ public static string GetDefaultValueSql([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(RelationalAnnotationNames.DefaultValueSql);
if (annotation != null)
@@ -469,7 +493,7 @@ public static string GetComputedColumnSql([NotNull] this IProperty property)
/// The property.
/// The identifier of the table-like store object containing the column.
/// The SQL expression that is used as the computed value for the column this property is mapped to.
- public static string GetComputedColumnSql([NotNull] this IProperty property, StoreObjectIdentifier storeObject)
+ public static string GetComputedColumnSql([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(RelationalAnnotationNames.ComputedColumnSql);
if (annotation != null)
@@ -547,7 +571,7 @@ public static string SetComputedColumnSql(
/// Whether the value of the computed column this property is mapped to is stored in the database,
/// or calculated when it is read.
///
- public static bool? GetIsStored([NotNull] this IProperty property, StoreObjectIdentifier storeObject)
+ public static bool? GetIsStored([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(RelationalAnnotationNames.IsStored);
if (annotation != null)
@@ -616,7 +640,7 @@ public static object GetDefaultValue([NotNull] this IProperty property)
/// The property.
/// The identifier of the table-like store object containing the column.
/// The object that is used as the default value for the column this property is mapped to.
- public static object GetDefaultValue([NotNull] this IProperty property, StoreObjectIdentifier storeObject)
+ public static object GetDefaultValue([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(RelationalAnnotationNames.DefaultValue);
if (annotation != null)
@@ -708,7 +732,7 @@ private static object ConvertDefaultValue([NotNull] IProperty property, [CanBeNu
/// The property.
/// The identifier of the table-like store object containing the column.
/// A flag indicating if the property as capable of storing only fixed-length data, such as strings.
- public static bool? IsFixedLength([NotNull] this IProperty property, StoreObjectIdentifier storeObject)
+ public static bool? IsFixedLength([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(RelationalAnnotationNames.IsFixedLength);
if (annotation != null)
@@ -786,7 +810,7 @@ public static bool IsColumnNullable([NotNull] this IProperty property)
/// The .
/// The identifier of the table-like store object containing the column.
/// if the mapped column is nullable; otherwise.
- public static bool IsColumnNullable([NotNull] this IProperty property, StoreObjectIdentifier storeObject)
+ public static bool IsColumnNullable([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
{
if (property.IsPrimaryKey())
{
@@ -821,7 +845,7 @@ public static string GetComment([NotNull] this IProperty property)
/// The property.
/// The identifier of the table-like store object containing the column.
/// The comment for the column this property is mapped to.
- public static string GetComment([NotNull] this IProperty property, StoreObjectIdentifier storeObject)
+ public static string GetComment([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(RelationalAnnotationNames.Comment);
if (annotation != null)
@@ -887,7 +911,7 @@ public static string GetCollation([NotNull] this IProperty property)
/// The property.
/// The identifier of the table-like store object containing the column.
/// The collation for the column this property is mapped to.
- public static string GetCollation([NotNull] this IProperty property, StoreObjectIdentifier storeObject)
+ public static string GetCollation([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(RelationalAnnotationNames.Collation);
if (annotation != null)
@@ -971,7 +995,7 @@ public static RelationalTypeMapping FindRelationalTypeMapping([NotNull] this IPr
/// The identifier of the table-like store object containing the column.
/// The type mapping, or if none was found.
public static RelationalTypeMapping FindRelationalTypeMapping(
- [NotNull] this IProperty property, StoreObjectIdentifier storeObject)
+ [NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
=> property.FindRelationalTypeMapping();
///
@@ -987,7 +1011,7 @@ public static RelationalTypeMapping FindRelationalTypeMapping(
/// The identifier of the table-like store object containing the column.
/// The property found, or if none was found.
public static IProperty FindSharedStoreObjectRootProperty(
- [NotNull] this IProperty property, StoreObjectIdentifier storeObject)
+ [NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
=> FindSharedObjectRootProperty(property, storeObject);
///
@@ -1003,7 +1027,7 @@ public static IProperty FindSharedStoreObjectRootProperty(
/// The identifier of the table-like store object containing the column.
/// The property found, or if none was found.
public static IMutableProperty FindSharedStoreObjectRootProperty(
- [NotNull] this IMutableProperty property, StoreObjectIdentifier storeObject)
+ [NotNull] this IMutableProperty property, in StoreObjectIdentifier storeObject)
=> (IMutableProperty)FindSharedObjectRootProperty(property, storeObject);
///
@@ -1019,10 +1043,10 @@ public static IMutableProperty FindSharedStoreObjectRootProperty(
/// The identifier of the table-like store object containing the column.
/// The property found, or if none was found.
public static IConventionProperty FindSharedStoreObjectRootProperty(
- [NotNull] this IConventionProperty property, StoreObjectIdentifier storeObject)
+ [NotNull] this IConventionProperty property, in StoreObjectIdentifier storeObject)
=> (IConventionProperty)FindSharedObjectRootProperty(property, storeObject);
- private static IProperty FindSharedObjectRootProperty([NotNull] IProperty property, StoreObjectIdentifier storeObject)
+ private static IProperty FindSharedObjectRootProperty([NotNull] IProperty property, in StoreObjectIdentifier storeObject)
{
Check.NotNull(property, nameof(property));
@@ -1040,10 +1064,18 @@ private static IProperty FindSharedObjectRootProperty([NotNull] IProperty proper
// Using a hashset is detrimental to the perf when there are no cycles
for (var i = 0; i < Metadata.Internal.RelationalEntityTypeExtensions.MaxEntityTypesSharingTable; i++)
{
- var linkedProperty = rootProperty.DeclaringEntityType
+ IProperty linkedProperty = null;
+ foreach (var p in rootProperty.DeclaringEntityType
.FindRowInternalForeignKeys(storeObject)
- .SelectMany(fk => fk.PrincipalEntityType.GetProperties())
- .FirstOrDefault(p => p.GetColumnName(storeObject) == column);
+ .SelectMany(fk => fk.PrincipalEntityType.GetProperties()))
+ {
+ if (p.GetColumnName(storeObject) == column)
+ {
+ linkedProperty = p;
+ break;
+ }
+ }
+
if (linkedProperty == null)
{
break;
@@ -1055,7 +1087,7 @@ private static IProperty FindSharedObjectRootProperty([NotNull] IProperty proper
return rootProperty == property ? null : rootProperty;
}
- private static IProperty FindSharedObjectRootPrimaryKeyProperty([NotNull] IProperty property, StoreObjectIdentifier storeObject)
+ private static IProperty FindSharedObjectRootPrimaryKeyProperty([NotNull] IProperty property, in StoreObjectIdentifier storeObject)
{
if (!property.IsPrimaryKey())
{
@@ -1081,7 +1113,7 @@ private static IProperty FindSharedObjectRootPrimaryKeyProperty([NotNull] IPrope
return principalProperty == property ? null : principalProperty;
}
- private static IProperty FindSharedObjectRootConcurrencyTokenProperty([NotNull] IProperty property, StoreObjectIdentifier storeObject)
+ private static IProperty FindSharedObjectRootConcurrencyTokenProperty([NotNull] IProperty property, in StoreObjectIdentifier storeObject)
{
if (!property.IsConcurrencyToken)
{
@@ -1123,7 +1155,7 @@ private static IProperty FindSharedObjectRootConcurrencyTokenProperty([NotNull]
/// The property.
/// The identifier of the table-like store object containing the column.
/// An object that stores property facet overrides.
- public static IAnnotatable FindOverrides([NotNull] this IProperty property, StoreObjectIdentifier storeObject)
+ public static IAnnotatable FindOverrides([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
=> RelationalPropertyOverrides.Find(property, storeObject);
///
@@ -1139,7 +1171,7 @@ public static IAnnotatable FindOverrides([NotNull] this IProperty property, Stor
/// The identifier of the table-like store object containing the column.
/// An object that stores property facet overrides.
public static IMutableAnnotatable GetOrCreateOverrides(
- [NotNull] this IMutableProperty property, StoreObjectIdentifier storeObject)
+ [NotNull] this IMutableProperty property, in StoreObjectIdentifier storeObject)
=> RelationalPropertyOverrides.GetOrCreate(property, storeObject);
///
@@ -1155,7 +1187,7 @@ public static IMutableAnnotatable GetOrCreateOverrides(
/// The identifier of the table-like store object containing the column.
/// An object that stores property facet overrides.
public static IConventionAnnotatable GetOrCreateOverrides(
- [NotNull] this IConventionProperty property, StoreObjectIdentifier storeObject)
+ [NotNull] this IConventionProperty property, in StoreObjectIdentifier storeObject)
=> RelationalPropertyOverrides.GetOrCreate(property, storeObject);
}
}
diff --git a/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs b/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs
index 83d9bc6027a..39167d2a7ef 100644
--- a/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs
+++ b/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs
@@ -600,7 +600,7 @@ private static bool IsIdentifyingPrincipal(IEntityType dependentEntityType, IEnt
/// The logger to use.
protected virtual void ValidateSharedColumnsCompatibility(
[NotNull] IReadOnlyList mappedTypes,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
[NotNull] IDiagnosticsLogger logger)
{
var concurrencyColumns = TableSharingConcurrencyTokenConvention.GetConcurrencyTokensMap(storeObject, mappedTypes);
@@ -643,8 +643,17 @@ protected virtual void ValidateSharedColumnsCompatibility(
{
foreach (var missingColumn in missingConcurrencyTokens)
{
- if (entityType.GetAllBaseTypesAscending().SelectMany(t => t.GetDeclaredProperties())
- .All(p => p.GetColumnName(storeObject) != missingColumn))
+ var columnFound = false;
+ foreach (var property in entityType.GetAllBaseTypesAscending().SelectMany(t => t.GetDeclaredProperties()))
+ {
+ if (property.GetColumnName(storeObject) == missingColumn)
+ {
+ columnFound = true;
+ break;
+ }
+ }
+
+ if (!columnFound)
{
throw new InvalidOperationException(
RelationalStrings.MissingConcurrencyColumn(entityType.DisplayName(), missingColumn, storeObject.DisplayName()));
@@ -666,7 +675,7 @@ protected virtual void ValidateCompatible(
[NotNull] IProperty property,
[NotNull] IProperty duplicateProperty,
[NotNull] string columnName,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
[NotNull] IDiagnosticsLogger logger)
{
if (property.IsNullable != duplicateProperty.IsNullable)
@@ -862,7 +871,7 @@ protected virtual void ValidateCompatible(
/// The object that is used as the default value for the column the property is mapped to.
protected virtual object GetDefaultColumnValue(
[NotNull] IProperty property,
- StoreObjectIdentifier storeObject)
+ in StoreObjectIdentifier storeObject)
{
var value = property.GetDefaultValue(storeObject);
var converter = property.GetValueConverter() ?? property.FindRelationalTypeMapping(storeObject)?.Converter;
@@ -880,7 +889,7 @@ protected virtual object GetDefaultColumnValue(
/// The logger to use.
protected virtual void ValidateSharedForeignKeysCompatibility(
[NotNull] IReadOnlyList mappedTypes,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
[NotNull] IDiagnosticsLogger logger)
{
if (storeObject.StoreObjectType != StoreObjectType.Table)
@@ -925,7 +934,7 @@ protected virtual void ValidateCompatible(
[NotNull] IForeignKey foreignKey,
[NotNull] IForeignKey duplicateForeignKey,
[NotNull] string foreignKeyName,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
[NotNull] IDiagnosticsLogger logger)
=> foreignKey.AreCompatible(duplicateForeignKey, storeObject, shouldThrow: true);
@@ -937,7 +946,7 @@ protected virtual void ValidateCompatible(
/// The logger to use.
protected virtual void ValidateSharedIndexesCompatibility(
[NotNull] IReadOnlyList mappedTypes,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
[NotNull] IDiagnosticsLogger logger)
{
var indexMappings = new Dictionary();
@@ -966,7 +975,7 @@ protected virtual void ValidateCompatible(
[NotNull] IIndex index,
[NotNull] IIndex duplicateIndex,
[NotNull] string indexName,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
[NotNull] IDiagnosticsLogger logger)
=> index.AreCompatible(duplicateIndex, storeObject, shouldThrow: true);
@@ -978,7 +987,7 @@ protected virtual void ValidateCompatible(
/// The logger to use.
protected virtual void ValidateSharedKeysCompatibility(
[NotNull] IReadOnlyList mappedTypes,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
[NotNull] IDiagnosticsLogger logger)
{
var keyMappings = new Dictionary();
@@ -1008,7 +1017,7 @@ protected virtual void ValidateCompatible(
[NotNull] IKey key,
[NotNull] IKey duplicateKey,
[NotNull] string keyName,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
[NotNull] IDiagnosticsLogger logger)
{
key.AreCompatible(duplicateKey, storeObject, shouldThrow: true);
diff --git a/src/EFCore.Relational/Infrastructure/RelationalPropertyExtensions.cs b/src/EFCore.Relational/Infrastructure/RelationalPropertyExtensions.cs
index c84edf5cc48..8ae4336b394 100644
--- a/src/EFCore.Relational/Infrastructure/RelationalPropertyExtensions.cs
+++ b/src/EFCore.Relational/Infrastructure/RelationalPropertyExtensions.cs
@@ -23,5 +23,23 @@ public static string FormatColumns(
[NotNull] this IEnumerable properties,
StoreObjectIdentifier storeObject)
=> "{" + string.Join(", ", properties.Select(p => "'" + p.GetColumnName(storeObject) + "'")) + "}";
+
+ ///
+ /// Creates a list of column names.
+ ///
+ /// The properties to format.
+ /// The identifier of the table-like store object containing the column.
+ /// A list of column names.
+ public static IReadOnlyList GetColumnNames(
+ [NotNull] this IEnumerable properties,
+ in StoreObjectIdentifier storeObject)
+ {
+ var propertyNames = new List();
+ foreach (var property in properties)
+ {
+ propertyNames.Add(property.GetColumnName(storeObject));
+ }
+ return propertyNames;
+ }
}
}
diff --git a/src/EFCore.Relational/Metadata/Conventions/RelationalValueGenerationConvention.cs b/src/EFCore.Relational/Metadata/Conventions/RelationalValueGenerationConvention.cs
index 13116d8b086..c41ea62a1a1 100644
--- a/src/EFCore.Relational/Metadata/Conventions/RelationalValueGenerationConvention.cs
+++ b/src/EFCore.Relational/Metadata/Conventions/RelationalValueGenerationConvention.cs
@@ -145,7 +145,7 @@ private void ProcessTableChanged(IConventionEntityTypeBuilder entityTypeBuilder,
/// The property.
/// The identifier of the store object.
/// The new store value generation strategy to set for the given property.
- public static ValueGenerated? GetValueGenerated([NotNull] IProperty property, StoreObjectIdentifier storeObject)
+ public static ValueGenerated? GetValueGenerated([NotNull] IProperty property, in StoreObjectIdentifier storeObject)
{
var valueGenerated = GetValueGenerated(property);
return valueGenerated ?? (property.GetComputedColumnSql(storeObject) != null
diff --git a/src/EFCore.Relational/Metadata/Conventions/SharedTableConvention.cs b/src/EFCore.Relational/Metadata/Conventions/SharedTableConvention.cs
index 13bad0c05d9..d375a36bd52 100644
--- a/src/EFCore.Relational/Metadata/Conventions/SharedTableConvention.cs
+++ b/src/EFCore.Relational/Metadata/Conventions/SharedTableConvention.cs
@@ -152,7 +152,7 @@ private static void TryUniquifyTableNames(
private static void TryUniquifyColumnNames(
IConventionEntityType entityType,
Dictionary properties,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
int maxLength)
{
foreach (var property in entityType.GetDeclaredProperties())
@@ -234,7 +234,7 @@ private static string TryUniquify(
private void TryUniquifyKeyNames(
IConventionEntityType entityType,
Dictionary keys,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
int maxLength)
{
foreach (var key in entityType.GetDeclaredKeys())
@@ -279,7 +279,7 @@ private void TryUniquifyKeyNames(
protected virtual bool AreCompatible(
[NotNull] IKey key,
[NotNull] IKey duplicateKey,
- StoreObjectIdentifier storeObject)
+ in StoreObjectIdentifier storeObject)
=> key.AreCompatible(duplicateKey, storeObject, shouldThrow: false);
private static string TryUniquify(
@@ -298,7 +298,7 @@ private static string TryUniquify(
private void TryUniquifyIndexNames(
IConventionEntityType entityType,
Dictionary indexes,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
int maxLength)
{
foreach (var index in entityType.GetDeclaredIndexes())
@@ -341,7 +341,7 @@ private void TryUniquifyIndexNames(
protected virtual bool AreCompatible(
[NotNull] IIndex index,
[NotNull] IIndex duplicateIndex,
- StoreObjectIdentifier storeObject)
+ in StoreObjectIdentifier storeObject)
=> index.AreCompatible(duplicateIndex, storeObject, shouldThrow: false);
private static string TryUniquify(
@@ -360,7 +360,7 @@ private static string TryUniquify(
private void TryUniquifyForeignKeyNames(
IConventionEntityType entityType,
Dictionary foreignKeys,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
int maxLength)
{
foreach (var foreignKey in entityType.GetDeclaredForeignKeys())
@@ -413,7 +413,7 @@ private void TryUniquifyForeignKeyNames(
protected virtual bool AreCompatible(
[NotNull] IForeignKey foreignKey,
[NotNull] IForeignKey duplicateForeignKey,
- StoreObjectIdentifier storeObject)
+ in StoreObjectIdentifier storeObject)
=> foreignKey.AreCompatible(duplicateForeignKey, storeObject, shouldThrow: false);
private static string TryUniquify(
diff --git a/src/EFCore.Relational/Metadata/Conventions/StoreGenerationConvention.cs b/src/EFCore.Relational/Metadata/Conventions/StoreGenerationConvention.cs
index 0dc9d276c97..23f11803720 100644
--- a/src/EFCore.Relational/Metadata/Conventions/StoreGenerationConvention.cs
+++ b/src/EFCore.Relational/Metadata/Conventions/StoreGenerationConvention.cs
@@ -112,7 +112,7 @@ public virtual void ProcessModelFinalizing(IConventionModelBuilder modelBuilder,
/// The identifier of the store object.
protected virtual void Validate(
[NotNull] IConventionProperty property,
- StoreObjectIdentifier storeObject)
+ in StoreObjectIdentifier storeObject)
{
if (property.GetDefaultValue(storeObject) != null)
{
diff --git a/src/EFCore.Relational/Metadata/Conventions/TableSharingConcurrencyTokenConvention.cs b/src/EFCore.Relational/Metadata/Conventions/TableSharingConcurrencyTokenConvention.cs
index 2d196ac25b0..b584c1ef101 100644
--- a/src/EFCore.Relational/Metadata/Conventions/TableSharingConcurrencyTokenConvention.cs
+++ b/src/EFCore.Relational/Metadata/Conventions/TableSharingConcurrencyTokenConvention.cs
@@ -131,7 +131,7 @@ public virtual void ProcessModelFinalizing(
///
[EntityFrameworkInternal]
public static Dictionary> GetConcurrencyTokensMap(
- StoreObjectIdentifier table, [NotNull] IReadOnlyList mappedTypes)
+ in StoreObjectIdentifier storeObject, [NotNull] IReadOnlyList mappedTypes)
{
if (mappedTypes.Count < 2)
{
@@ -156,7 +156,7 @@ public static Dictionary> GetConcurrencyTokensMap(
continue;
}
- var columnName = property.GetColumnName(table);
+ var columnName = property.GetColumnName(storeObject);
if (columnName == null)
{
continue;
diff --git a/src/EFCore.Relational/Metadata/Internal/RelationalForeignKeyExtensions.cs b/src/EFCore.Relational/Metadata/Internal/RelationalForeignKeyExtensions.cs
index 2931f39b4f3..719044bcd56 100644
--- a/src/EFCore.Relational/Metadata/Internal/RelationalForeignKeyExtensions.cs
+++ b/src/EFCore.Relational/Metadata/Internal/RelationalForeignKeyExtensions.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 JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Diagnostics;
@@ -26,7 +27,7 @@ public static class RelationalForeignKeyExtensions
public static bool AreCompatible(
[NotNull] this IForeignKey foreignKey,
[NotNull] IForeignKey duplicateForeignKey,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
bool shouldThrow)
{
var principalType = foreignKey.PrincipalEntityType;
@@ -53,8 +54,7 @@ public static bool AreCompatible(
return false;
}
- if (!foreignKey.Properties.Select(p => p.GetColumnName(storeObject))
- .SequenceEqual(duplicateForeignKey.Properties.Select(p => p.GetColumnName(storeObject))))
+ if (!SameColumnNames(foreignKey.Properties, duplicateForeignKey.Properties, storeObject))
{
if (shouldThrow)
{
@@ -75,8 +75,7 @@ public static bool AreCompatible(
return false;
}
- if (!foreignKey.PrincipalKey.Properties.Select(p => p.GetColumnName(storeObject))
- .SequenceEqual(duplicateForeignKey.PrincipalKey.Properties.Select(p => p.GetColumnName(storeObject))))
+ if (!SameColumnNames(foreignKey.PrincipalKey.Properties, duplicateForeignKey.PrincipalKey.Properties, storeObject))
{
if (shouldThrow)
{
@@ -138,6 +137,12 @@ public static bool AreCompatible(
}
return true;
+
+ static bool SameColumnNames(
+ IReadOnlyList properties,
+ IReadOnlyList duplicateProperties,
+ in StoreObjectIdentifier storeObject)
+ => properties.GetColumnNames(storeObject).SequenceEqual(duplicateProperties.GetColumnNames(storeObject));
}
}
}
diff --git a/src/EFCore.Relational/Metadata/Internal/RelationalIndexExtensions.cs b/src/EFCore.Relational/Metadata/Internal/RelationalIndexExtensions.cs
index 66a2c9343f1..7b66c4f5a41 100644
--- a/src/EFCore.Relational/Metadata/Internal/RelationalIndexExtensions.cs
+++ b/src/EFCore.Relational/Metadata/Internal/RelationalIndexExtensions.cs
@@ -26,11 +26,11 @@ public static class RelationalIndexExtensions
public static bool AreCompatible(
[NotNull] this IIndex index,
[NotNull] IIndex duplicateIndex,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
bool shouldThrow)
{
- if (!index.Properties.Select(p => p.GetColumnName(storeObject))
- .SequenceEqual(duplicateIndex.Properties.Select(p => p.GetColumnName(storeObject))))
+ if (!index.Properties.GetColumnNames(storeObject)
+ .SequenceEqual(duplicateIndex.Properties.GetColumnNames(storeObject)))
{
if (shouldThrow)
{
diff --git a/src/EFCore.Relational/Metadata/Internal/RelationalKeyExtensions.cs b/src/EFCore.Relational/Metadata/Internal/RelationalKeyExtensions.cs
index 46b66f5dd2b..9f88ed257ea 100644
--- a/src/EFCore.Relational/Metadata/Internal/RelationalKeyExtensions.cs
+++ b/src/EFCore.Relational/Metadata/Internal/RelationalKeyExtensions.cs
@@ -26,11 +26,11 @@ public static class RelationalKeyExtensions
public static bool AreCompatible(
[NotNull] this IKey key,
[NotNull] IKey duplicateKey,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
bool shouldThrow)
{
- if (!key.Properties.Select(p => p.GetColumnName(storeObject))
- .SequenceEqual(duplicateKey.Properties.Select(p => p.GetColumnName(storeObject))))
+ if (!key.Properties.GetColumnNames(storeObject)
+ .SequenceEqual(duplicateKey.Properties.GetColumnNames(storeObject)))
{
if (shouldThrow)
{
diff --git a/src/EFCore.Relational/Metadata/Internal/RelationalPropertyOverrides.cs b/src/EFCore.Relational/Metadata/Internal/RelationalPropertyOverrides.cs
index 1c8c6a606a7..31b19c813bc 100644
--- a/src/EFCore.Relational/Metadata/Internal/RelationalPropertyOverrides.cs
+++ b/src/EFCore.Relational/Metadata/Internal/RelationalPropertyOverrides.cs
@@ -60,7 +60,7 @@ public virtual string SetColumnName([CanBeNull] string columnName, Configuration
/// 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 static RelationalPropertyOverrides Find([NotNull] IProperty property, StoreObjectIdentifier storeObject)
+ public static RelationalPropertyOverrides Find([NotNull] IProperty property, in StoreObjectIdentifier storeObject)
{
var tableOverrides = (SortedDictionary)
property[RelationalAnnotationNames.RelationalOverrides];
@@ -77,7 +77,7 @@ public static RelationalPropertyOverrides Find([NotNull] IProperty property, Sto
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public static RelationalPropertyOverrides GetOrCreate(
- [NotNull] IMutableProperty property, StoreObjectIdentifier storeObject)
+ [NotNull] IMutableProperty property, in StoreObjectIdentifier storeObject)
{
var tableOverrides = (SortedDictionary)
property[RelationalAnnotationNames.RelationalOverrides];
@@ -103,7 +103,7 @@ public static RelationalPropertyOverrides GetOrCreate(
/// doing so can result in application failures when updating to a new Entity Framework Core release.
///
public static RelationalPropertyOverrides GetOrCreate(
- [NotNull] IConventionProperty property, StoreObjectIdentifier storeObject)
+ [NotNull] IConventionProperty property, in StoreObjectIdentifier storeObject)
=> GetOrCreate((IMutableProperty)property, storeObject);
}
}
diff --git a/src/EFCore.Relational/Metadata/StoreObjectIdentifier.cs b/src/EFCore.Relational/Metadata/StoreObjectIdentifier.cs
index 734ea2cde0f..e3303a2369c 100644
--- a/src/EFCore.Relational/Metadata/StoreObjectIdentifier.cs
+++ b/src/EFCore.Relational/Metadata/StoreObjectIdentifier.cs
@@ -10,8 +10,15 @@ namespace Microsoft.EntityFrameworkCore.Metadata
///
/// A type that represents the id of a store object
///
- public struct StoreObjectIdentifier : IComparable
+ public readonly struct StoreObjectIdentifier : IComparable
{
+ private StoreObjectIdentifier(StoreObjectType storeObjectType, string name, string schema = null)
+ {
+ StoreObjectType = storeObjectType;
+ Name = name;
+ Schema = schema;
+ }
+
///
/// Creates a table id.
///
@@ -22,7 +29,7 @@ public static StoreObjectIdentifier Table([NotNull] string name, [CanBeNull] str
{
Check.NotNull(name, nameof(name));
- return new StoreObjectIdentifier { StoreObjectType = StoreObjectType.Table, Name = name, Schema = schema };
+ return new StoreObjectIdentifier(StoreObjectType.Table, name, schema);
}
///
@@ -35,7 +42,7 @@ public static StoreObjectIdentifier View([NotNull] string name, [CanBeNull] stri
{
Check.NotNull(name, nameof(name));
- return new StoreObjectIdentifier { StoreObjectType = StoreObjectType.View, Name = name, Schema = schema };
+ return new StoreObjectIdentifier(StoreObjectType.View, name, schema);
}
///
@@ -47,7 +54,7 @@ public static StoreObjectIdentifier SqlQuery([NotNull] IEntityType entityType)
{
Check.NotNull(entityType, nameof(entityType));
- return new StoreObjectIdentifier { StoreObjectType = StoreObjectType.SqlQuery, Name = entityType.GetDefaultSqlQueryName() };
+ return new StoreObjectIdentifier(StoreObjectType.SqlQuery, entityType.GetDefaultSqlQueryName());
}
///
@@ -59,7 +66,7 @@ public static StoreObjectIdentifier SqlQuery([NotNull] string name)
{
Check.NotNull(name, nameof(name));
- return new StoreObjectIdentifier { StoreObjectType = StoreObjectType.SqlQuery, Name = name };
+ return new StoreObjectIdentifier(StoreObjectType.SqlQuery, name);
}
///
@@ -71,23 +78,23 @@ public static StoreObjectIdentifier DbFunction([NotNull] string modelName)
{
Check.NotNull(modelName, nameof(modelName));
- return new StoreObjectIdentifier { StoreObjectType = StoreObjectType.Function, Name = modelName };
+ return new StoreObjectIdentifier(StoreObjectType.Function, modelName);
}
///
/// Gets the table-like store object type.
///
- public StoreObjectType StoreObjectType { get; private set; }
+ public StoreObjectType StoreObjectType { get; }
///
/// Gets the table-like store object name.
///
- public string Name { get; private set; }
+ public string Name { get; }
///
/// Gets the table-like store object schema.
///
- public string Schema { get; private set; }
+ public string Schema { get; }
///
public int CompareTo(StoreObjectIdentifier other)
diff --git a/src/EFCore.SqlServer/Extensions/SqlServerIndexExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerIndexExtensions.cs
index ef4b3b6f21e..7935e52ba54 100644
--- a/src/EFCore.SqlServer/Extensions/SqlServerIndexExtensions.cs
+++ b/src/EFCore.SqlServer/Extensions/SqlServerIndexExtensions.cs
@@ -29,7 +29,7 @@ public static class SqlServerIndexExtensions
/// The index.
/// The identifier of the store object.
/// if the index is clustered.
- public static bool? IsClustered([NotNull] this IIndex index, StoreObjectIdentifier storeObject)
+ public static bool? IsClustered([NotNull] this IIndex index, in StoreObjectIdentifier storeObject)
{
var annotation = index.FindAnnotation(SqlServerAnnotationNames.Clustered);
if (annotation != null)
@@ -40,7 +40,7 @@ public static class SqlServerIndexExtensions
return GetDefaultIsClustered(index, storeObject);
}
- private static bool? GetDefaultIsClustered([NotNull] IIndex index, StoreObjectIdentifier storeObject)
+ private static bool? GetDefaultIsClustered([NotNull] IIndex index, in StoreObjectIdentifier storeObject)
{
var sharedTableRootIndex = index.FindSharedObjectRootIndex(storeObject);
return sharedTableRootIndex?.IsClustered(storeObject);
diff --git a/src/EFCore.SqlServer/Extensions/SqlServerKeyExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerKeyExtensions.cs
index 9103d379d16..c1faac01b87 100644
--- a/src/EFCore.SqlServer/Extensions/SqlServerKeyExtensions.cs
+++ b/src/EFCore.SqlServer/Extensions/SqlServerKeyExtensions.cs
@@ -27,7 +27,7 @@ public static class SqlServerKeyExtensions
/// The key.
/// The identifier of the store object.
/// if the key is clustered.
- public static bool? IsClustered([NotNull] this IKey key, StoreObjectIdentifier storeObject)
+ public static bool? IsClustered([NotNull] this IKey key, in StoreObjectIdentifier storeObject)
{
var annotation = key.FindAnnotation(SqlServerAnnotationNames.Clustered);
if (annotation != null)
@@ -38,7 +38,7 @@ public static class SqlServerKeyExtensions
return GetDefaultIsClustered(key, storeObject);
}
- private static bool? GetDefaultIsClustered([NotNull] IKey key, StoreObjectIdentifier storeObject)
+ private static bool? GetDefaultIsClustered([NotNull] IKey key, in StoreObjectIdentifier storeObject)
{
var sharedTableRootKey = key.FindSharedObjectRootKey(storeObject);
return sharedTableRootKey?.IsClustered(storeObject);
diff --git a/src/EFCore.SqlServer/Extensions/SqlServerPropertyExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerPropertyExtensions.cs
index 060e0d6ff47..e0f91a42f11 100644
--- a/src/EFCore.SqlServer/Extensions/SqlServerPropertyExtensions.cs
+++ b/src/EFCore.SqlServer/Extensions/SqlServerPropertyExtensions.cs
@@ -160,7 +160,7 @@ public static ISequence FindHiLoSequence([NotNull] this IProperty property)
/// The property.
/// The identifier of the store object.
/// The identity seed.
- public static int? GetIdentitySeed([NotNull] this IProperty property, StoreObjectIdentifier storeObject)
+ public static int? GetIdentitySeed([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(SqlServerAnnotationNames.IdentitySeed);
if (annotation != null)
@@ -224,7 +224,7 @@ public static void SetIdentitySeed([NotNull] this IMutableProperty property, int
/// The property.
/// The identifier of the store object.
/// The identity increment.
- public static int? GetIdentityIncrement([NotNull] this IProperty property, StoreObjectIdentifier storeObject)
+ public static int? GetIdentityIncrement([NotNull] this IProperty property, in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(SqlServerAnnotationNames.IdentityIncrement);
if (annotation != null)
@@ -317,7 +317,7 @@ public static SqlServerValueGenerationStrategy GetValueGenerationStrategy([NotNu
/// The strategy, or if none was set.
public static SqlServerValueGenerationStrategy GetValueGenerationStrategy(
[NotNull] this IProperty property,
- StoreObjectIdentifier storeObject)
+ in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(SqlServerAnnotationNames.ValueGenerationStrategy);
if (annotation != null)
diff --git a/src/EFCore.SqlServer/Internal/SqlServerModelValidator.cs b/src/EFCore.SqlServer/Internal/SqlServerModelValidator.cs
index fb33596edde..80fa1831ea4 100644
--- a/src/EFCore.SqlServer/Internal/SqlServerModelValidator.cs
+++ b/src/EFCore.SqlServer/Internal/SqlServerModelValidator.cs
@@ -230,7 +230,7 @@ protected override void ValidateSharedTableCompatibility(
///
protected override void ValidateSharedColumnsCompatibility(
IReadOnlyList mappedTypes,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
IDiagnosticsLogger logger)
{
base.ValidateSharedColumnsCompatibility(mappedTypes, storeObject, logger);
@@ -264,7 +264,7 @@ protected override void ValidateCompatible(
IProperty property,
IProperty duplicateProperty,
string columnName,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
IDiagnosticsLogger logger)
{
base.ValidateCompatible(property, duplicateProperty, columnName, storeObject, logger);
@@ -338,7 +338,7 @@ protected override void ValidateCompatible(
IKey key,
IKey duplicateKey,
string keyName,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
IDiagnosticsLogger logger)
{
base.ValidateCompatible(key, duplicateKey, keyName, storeObject, logger);
@@ -351,7 +351,7 @@ protected override void ValidateCompatible(
IIndex index,
IIndex duplicateIndex,
string indexName,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
IDiagnosticsLogger logger)
{
base.ValidateCompatible(index, duplicateIndex, indexName, storeObject, logger);
diff --git a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerSharedTableConvention.cs b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerSharedTableConvention.cs
index 1b213d12f12..329bd75cdb5 100644
--- a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerSharedTableConvention.cs
+++ b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerSharedTableConvention.cs
@@ -31,12 +31,12 @@ public SqlServerSharedTableConvention(
}
///
- protected override bool AreCompatible(IKey key, IKey duplicateKey, StoreObjectIdentifier storeObject)
+ protected override bool AreCompatible(IKey key, IKey duplicateKey, in StoreObjectIdentifier storeObject)
=> base.AreCompatible(key, duplicateKey, storeObject)
&& key.AreCompatibleForSqlServer(duplicateKey, storeObject, shouldThrow: false);
///
- protected override bool AreCompatible(IIndex index, IIndex duplicateIndex, StoreObjectIdentifier storeObject)
+ protected override bool AreCompatible(IIndex index, IIndex duplicateIndex, in StoreObjectIdentifier storeObject)
=> base.AreCompatible(index, duplicateIndex, storeObject)
&& index.AreCompatibleForSqlServer(duplicateIndex, storeObject, shouldThrow: false);
}
diff --git a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerStoreGenerationConvention.cs b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerStoreGenerationConvention.cs
index 72f0599c2e7..f99cd49b5d2 100644
--- a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerStoreGenerationConvention.cs
+++ b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerStoreGenerationConvention.cs
@@ -97,7 +97,7 @@ public override void ProcessPropertyAnnotationChanged(
}
///
- protected override void Validate(IConventionProperty property, StoreObjectIdentifier storeObject)
+ protected override void Validate(IConventionProperty property, in StoreObjectIdentifier storeObject)
{
if (property.GetValueGenerationStrategyConfigurationSource() != null)
{
diff --git a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerValueGenerationConvention.cs b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerValueGenerationConvention.cs
index f15f394b010..987a2e205f1 100644
--- a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerValueGenerationConvention.cs
+++ b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerValueGenerationConvention.cs
@@ -75,7 +75,7 @@ public override void ProcessPropertyAnnotationChanged(
/// The property.
/// The identifier of the store object.
/// The store value generation strategy to set for the given property.
- public static new ValueGenerated? GetValueGenerated([NotNull] IProperty property, StoreObjectIdentifier storeObject)
+ public static new ValueGenerated? GetValueGenerated([NotNull] IProperty property, in StoreObjectIdentifier storeObject)
=> RelationalValueGenerationConvention.GetValueGenerated(property, storeObject)
?? (property.GetValueGenerationStrategy(storeObject) != SqlServerValueGenerationStrategy.None
? ValueGenerated.OnAdd
diff --git a/src/EFCore.SqlServer/Metadata/Internal/SqlServerIndexExtensions.cs b/src/EFCore.SqlServer/Metadata/Internal/SqlServerIndexExtensions.cs
index b672bda79e6..0bb6170236c 100644
--- a/src/EFCore.SqlServer/Metadata/Internal/SqlServerIndexExtensions.cs
+++ b/src/EFCore.SqlServer/Metadata/Internal/SqlServerIndexExtensions.cs
@@ -25,19 +25,14 @@ public static class SqlServerIndexExtensions
public static bool AreCompatibleForSqlServer(
[NotNull] this IIndex index,
[NotNull] IIndex duplicateIndex,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
bool shouldThrow)
{
if (index.GetIncludeProperties() != duplicateIndex.GetIncludeProperties())
{
if (index.GetIncludeProperties() == null
|| duplicateIndex.GetIncludeProperties() == null
- || !index.GetIncludeProperties().Select(
- p => index.DeclaringEntityType.FindProperty(p).GetColumnName(storeObject))
- .SequenceEqual(
- duplicateIndex.GetIncludeProperties().Select(
- p => duplicateIndex.DeclaringEntityType.FindProperty(p)
- .GetColumnName(storeObject))))
+ || !SameColumnNames(index, duplicateIndex, storeObject))
{
if (shouldThrow)
{
@@ -109,6 +104,14 @@ public static bool AreCompatibleForSqlServer(
}
return true;
+
+ static bool SameColumnNames(IIndex index, IIndex duplicateIndex, StoreObjectIdentifier storeObject)
+ => index.GetIncludeProperties().Select(
+ p => index.DeclaringEntityType.FindProperty(p).GetColumnName(storeObject))
+ .SequenceEqual(
+ duplicateIndex.GetIncludeProperties().Select(
+ p => duplicateIndex.DeclaringEntityType.FindProperty(p)
+ .GetColumnName(storeObject)));
}
private static string FormatInclude(IIndex index, StoreObjectIdentifier storeObject)
diff --git a/src/EFCore.SqlServer/Metadata/Internal/SqlServerKeyExtensions.cs b/src/EFCore.SqlServer/Metadata/Internal/SqlServerKeyExtensions.cs
index eb43fd235e1..e085b056611 100644
--- a/src/EFCore.SqlServer/Metadata/Internal/SqlServerKeyExtensions.cs
+++ b/src/EFCore.SqlServer/Metadata/Internal/SqlServerKeyExtensions.cs
@@ -24,7 +24,7 @@ public static class SqlServerKeyExtensions
public static bool AreCompatibleForSqlServer(
[NotNull] this IKey key,
[NotNull] IKey duplicateKey,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
bool shouldThrow)
{
if (key.IsClustered(storeObject)
diff --git a/src/EFCore.Sqlite.Core/Extensions/SqlitePropertyExtensions.cs b/src/EFCore.Sqlite.Core/Extensions/SqlitePropertyExtensions.cs
index 5e2d62c75ac..610e3e29d8f 100644
--- a/src/EFCore.Sqlite.Core/Extensions/SqlitePropertyExtensions.cs
+++ b/src/EFCore.Sqlite.Core/Extensions/SqlitePropertyExtensions.cs
@@ -29,7 +29,7 @@ public static class SqlitePropertyExtensions
/// The SRID to use when creating a column for this property.
public static int? GetSrid(
[NotNull] this IProperty property,
- StoreObjectIdentifier storeObject)
+ in StoreObjectIdentifier storeObject)
{
var annotation = property.FindAnnotation(SqliteAnnotationNames.Srid);
if (annotation != null)
diff --git a/src/EFCore.Sqlite.Core/Internal/SqliteModelValidator.cs b/src/EFCore.Sqlite.Core/Internal/SqliteModelValidator.cs
index 359413d1e8c..964eca6035d 100644
--- a/src/EFCore.Sqlite.Core/Internal/SqliteModelValidator.cs
+++ b/src/EFCore.Sqlite.Core/Internal/SqliteModelValidator.cs
@@ -93,7 +93,7 @@ protected override void ValidateCompatible(
IProperty property,
IProperty duplicateProperty,
string columnName,
- StoreObjectIdentifier storeObject,
+ in StoreObjectIdentifier storeObject,
IDiagnosticsLogger logger)
{
base.ValidateCompatible(property, duplicateProperty, columnName, storeObject, logger);