/// <summary> /// Returns the default name that would be used for this index. /// </summary> /// <param name="index"> The index. </param> /// <param name="storeObject"> The identifier of the store object. </param> /// <returns> The default name that would be used for this index. </returns> public static string GetDefaultDatabaseName([NotNull] this IIndex index, StoreObjectIdentifier storeObject) { var propertyNames = index.Properties.Select(p => p.GetColumnName(storeObject)).ToList(); 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 .FindRowInternalForeignKeys(storeObject) .SelectMany(fk => fk.PrincipalEntityType.GetIndexes()) .FirstOrDefault(i => i.Properties.Select(p => p.GetColumnName(storeObject)).SequenceEqual(propertyNames)); if (linkedIndex == null) { break; } rootIndex = linkedIndex; } if (rootIndex != index) { return(rootIndex.GetDatabaseName(storeObject)); } var baseName = new StringBuilder() .Append("IX_") .Append(storeObject.Name) .Append("_") .AppendJoin(propertyNames, "_") .ToString(); return(Uniquifier.Truncate(baseName, index.DeclaringEntityType.Model.GetMaxIdentifierLength())); }
/// <summary> /// Returns the default key constraint name that would be used for this key. /// </summary> /// <param name="key"> The key. </param> /// <returns> The default key constraint name that would be used for this key. </returns> public static string GetDefaultName([NotNull] this IKey key) { var sharedTablePrincipalPrimaryKeyProperty = key.Properties[0].FindSharedRootPrimaryKeyProperty(); if (sharedTablePrincipalPrimaryKeyProperty != null) { return(sharedTablePrincipalPrimaryKeyProperty.FindContainingPrimaryKey().GetName()); } var builder = new StringBuilder(); var tableName = key.DeclaringEntityType.GetTableName() ?? key.DeclaringEntityType.GetViewName(); if (key.IsPrimaryKey()) { builder .Append("PK_") .Append(tableName); } else { builder .Append("AK_") .Append(tableName) .Append("_") .AppendJoin(key.Properties.Select(p => p.GetColumnName()), "_"); } return(Uniquifier.Truncate(builder.ToString(), key.DeclaringEntityType.Model.GetMaxIdentifierLength())); }
/// <summary> /// Returns the default table name that would be used for this entity type. /// </summary> /// <param name="entityType">The entity type to get the table name for.</param> /// <param name="truncate">A value indicating whether the name should be truncated to the max identifier length.</param> /// <returns>The default name of the table to which the entity type would be mapped.</returns> public static string?GetDefaultTableName(this IReadOnlyEntityType entityType, bool truncate = true) { var ownership = entityType.FindOwnership(); if (ownership != null && ownership.IsUnique) { return(ownership.PrincipalEntityType.GetTableName()); } var name = entityType.ShortName(); if (entityType.HasSharedClrType && ownership != null #pragma warning disable EF1001 // Internal EF Core API usage. && entityType.Name == ownership.PrincipalEntityType.GetOwnedName(name, ownership.PrincipalToDependent !.Name)) #pragma warning restore EF1001 // Internal EF Core API usage. { var ownerTypeTable = ownership.PrincipalEntityType.GetTableName(); name = ownerTypeTable != null ? $"{ownerTypeTable}_{ownership.PrincipalToDependent.Name}" : $"{ownership.PrincipalToDependent.Name}_{name}"; } return(truncate ? Uniquifier.Truncate(name, entityType.Model.GetMaxIdentifierLength()) : name); }
/// <summary> /// Generates a unique name for the new joint entity type. /// </summary> /// <param name="skipNavigation">The target skip navigation.</param> /// <returns>A unique entity type name.</returns> protected virtual string GenerateJoinTypeName(IConventionSkipNavigation skipNavigation) { var inverseSkipNavigation = skipNavigation.Inverse; Check.DebugAssert( inverseSkipNavigation?.Inverse == skipNavigation, "Inverse's inverse should be the original skip navigation"); var declaringEntityType = skipNavigation.DeclaringEntityType; var inverseEntityType = inverseSkipNavigation.DeclaringEntityType; var model = declaringEntityType.Model; var joinEntityTypeName = declaringEntityType.ShortName(); var inverseName = inverseEntityType.ShortName(); joinEntityTypeName = StringComparer.Ordinal.Compare(joinEntityTypeName, inverseName) < 0 ? joinEntityTypeName + inverseName : inverseName + joinEntityTypeName; if (model.FindEntityType(joinEntityTypeName) != null) { var otherIdentifiers = model.GetEntityTypes().ToDictionary(et => et.Name, _ => 0); joinEntityTypeName = Uniquifier.Uniquify( joinEntityTypeName, otherIdentifiers, int.MaxValue); } return(joinEntityTypeName); }
private void CreateJoinEntityType(IConventionSkipNavigationBuilder skipNavigationBuilder) { var skipNavigation = (SkipNavigation)skipNavigationBuilder.Metadata; if (skipNavigation.ForeignKey != null || !skipNavigation.IsCollection) { return; } var inverseSkipNavigation = skipNavigation.Inverse; if (inverseSkipNavigation == null || inverseSkipNavigation.ForeignKey != null || !inverseSkipNavigation.IsCollection) { return; } Check.DebugAssert(inverseSkipNavigation.Inverse == skipNavigation, "Inverse's inverse should be the original skip navigation"); var declaringEntityType = skipNavigation.DeclaringEntityType; var inverseEntityType = inverseSkipNavigation.DeclaringEntityType; var model = declaringEntityType.Model; var joinEntityTypeName = declaringEntityType.ShortName() + inverseEntityType.ShortName(); if (model.FindEntityType(joinEntityTypeName) != null) { var otherIdentifiers = model.GetEntityTypes().ToDictionary(et => et.Name, et => 0); joinEntityTypeName = Uniquifier.Uniquify( joinEntityTypeName, otherIdentifiers, int.MaxValue); } var joinEntityTypeBuilder = model.Builder.SharedTypeEntity( joinEntityTypeName, Model.DefaultPropertyBagType, ConfigurationSource.Convention); var leftForeignKey = CreateSkipNavigationForeignKey(skipNavigation, joinEntityTypeBuilder); if (leftForeignKey == null) { model.Builder.HasNoEntityType(joinEntityTypeBuilder.Metadata, ConfigurationSource.Convention); return; } var rightForeignKey = CreateSkipNavigationForeignKey(inverseSkipNavigation, joinEntityTypeBuilder); if (rightForeignKey == null) { model.Builder.HasNoEntityType(joinEntityTypeBuilder.Metadata, ConfigurationSource.Convention); return; } skipNavigation.Builder.HasForeignKey(leftForeignKey, ConfigurationSource.Convention); inverseSkipNavigation.Builder.HasForeignKey(rightForeignKey, ConfigurationSource.Convention); }
private static string GetDefaultName(IIndex index) { var baseName = new StringBuilder() .Append(index.DeclaringEntityType.GetTableName()) .Append("_ix_") .AppendJoin("_", index.Properties.Select(p => p.GetColumnName())) .ToString(); return(Uniquifier.Truncate(baseName, index.DeclaringEntityType.Model.GetMaxIdentifierLength())); }
private static string?FindArglistParameterName(IMethodSymbol symbol) { if (symbol.IsVararg) { var uniquifier = new Uniquifier(symbol.Parameters.Select(a => a.Name)); return(uniquifier.GetUniqueName("arglist")); } return(null); }
public SingleTypeOrValueTuple Build(string?mockMemberName = null) { mockMemberName ??= string.Empty; int count = Items.Count; SingleTypeOrValueTuple.Entry[] entries = new SingleTypeOrValueTuple.Entry[Items.Count]; if (count > 0) { if (count > 1) { var uniquifier = new Uniquifier(new[] { mockMemberName }); for (int i = 0; i < count; i++) { var item = Items[i]; string name = item.OriginalName; name = name == mockMemberName ? name + "_" : name; if (IsNameValidForPosition(name, i)) { entries[i] = new SingleTypeOrValueTuple.Entry( item.OriginalName, item.Type, item.IsReturnValue, uniquifier.GetUniqueName(name)); } } for (int i = 0; i < count; i++) { var item = Items[i]; string name = item.OriginalName; name = name == mockMemberName ? name + "_" : name; if (!IsNameValidForPosition(name, i)) { entries[i] = new SingleTypeOrValueTuple.Entry( item.OriginalName, item.Type, item.IsReturnValue, uniquifier.GetUniqueName(name + "_")); } } } else { var item = Items[0]; string name = item.OriginalName; name = name == mockMemberName ? name + "_" : name; entries[0] = new SingleTypeOrValueTuple.Entry(item.OriginalName, item.Type, item.IsReturnValue, name); } } return(new SingleTypeOrValueTuple(entries)); }
/// <summary> /// Returns the default column name to which the property would be mapped. /// </summary> /// <param name="property"> The property. </param> /// <returns> The default column name to which the property would be mapped. </returns> public static string GetDefaultColumnName([NotNull] this IProperty property) { var sharedTablePrincipalPrimaryKeyProperty = property.FindSharedTableRootPrimaryKeyProperty(); if (sharedTablePrincipalPrimaryKeyProperty != null) { return(sharedTablePrincipalPrimaryKeyProperty.GetColumnName()); } var entityType = property.DeclaringEntityType; StringBuilder builder = null; do { var ownership = entityType.GetForeignKeys().SingleOrDefault(fk => fk.IsOwnership); if (ownership == null) { entityType = null; } else { var ownerType = ownership.PrincipalEntityType; var table = entityType.GetTableName(); if (table != null && table == ownerType.GetTableName() && entityType.GetSchema() == ownerType.GetSchema()) { if (builder == null) { builder = new StringBuilder(); } builder.Insert(0, "_"); builder.Insert(0, ownership.PrincipalToDependent.Name); entityType = ownerType; } else { entityType = null; } } }while (entityType != null); var baseName = property.Name; if (builder != null) { builder.Append(baseName); baseName = builder.ToString(); } return(Uniquifier.Truncate(baseName, property.DeclaringEntityType.Model.GetMaxIdentifierLength())); }
/// <summary> /// Returns the default name that would be used for this index. /// </summary> /// <param name="index">The index.</param> /// <returns>The default name that would be used for this index.</returns> public static string GetDefaultDatabaseName(this IReadOnlyIndex index) { var tableName = index.DeclaringEntityType.GetTableName(); var baseName = new StringBuilder() .Append("IX_") .Append(tableName) .Append('_') .AppendJoin(index.Properties.Select(p => p.GetColumnBaseName()), "_") .ToString(); return(Uniquifier.Truncate(baseName, index.DeclaringEntityType.Model.GetMaxIdentifierLength())); }
private static string GetDefaultName(IMutableForeignKey key) { var baseName = new StringBuilder() .Append(key.DeclaringEntityType.GetTableName()) .Append("_") .Append(key.PrincipalEntityType.GetTableName()) .Append("_") .AppendJoin("_", key.PrincipalKey.Properties.Select(p => p.GetColumnName())) .Append("_fkey") .ToString(); return(Uniquifier.Truncate(baseName, key.DeclaringEntityType.Model.GetMaxIdentifierLength())); }
/// <summary> /// Returns the default constraint name that would be used for this foreign key. /// </summary> /// <param name="foreignKey"> The foreign key. </param> /// <returns> The default constraint name that would be used for this foreign key. </returns> public static string GetDefaultName([NotNull] this IForeignKey foreignKey) { var baseName = new StringBuilder() .Append("FK_") .Append(foreignKey.DeclaringEntityType.GetTableName()) .Append("_") .Append(foreignKey.PrincipalEntityType.GetTableName()) .Append("_") .AppendJoin(foreignKey.Properties.Select(p => p.GetColumnName()), "_") .ToString(); return(Uniquifier.Truncate(baseName, foreignKey.DeclaringEntityType.Model.GetMaxIdentifierLength())); }
/// <summary> /// Returns the default name that would be used for this index. /// </summary> /// <param name="index"> The index. </param> /// <returns> The default name that would be used for this index. </returns> public static string GetDefaultName([NotNull] this IIndex index) { var tableName = index.DeclaringEntityType.GetTableName(); var schema = index.DeclaringEntityType.GetSchema(); var baseName = new StringBuilder() .Append("IX_") .Append(tableName) .Append("_") .AppendJoin(index.Properties.Select(p => p.GetColumnName(tableName, schema)), "_") .ToString(); return(Uniquifier.Truncate(baseName, index.DeclaringEntityType.Model.GetMaxIdentifierLength())); }
private MemberDeclarationSyntax MockSetVirtualMethod() { var uniquifier = new Uniquifier(Symbol.Parameters.Select(p => p.Name)); var parameterList = F.SeparatedList(Symbol.Parameters.Select(a => F.Parameter(F.Identifier(a.Name)).WithType(TypesForSymbols.ParseTypeName(a.Type, a.NullableOrOblivious())))) .Add(F.Parameter(F.Identifier(uniquifier.GetUniqueName("value"))).WithType(ValueTypeSyntax)); return(F.MethodDeclaration(F.PredefinedType(F.Token(SyntaxKind.VoidKeyword)), F.Identifier(MemberMockName)) .WithModifiers(F.TokenList(F.Token(SyntaxKind.ProtectedKeyword), F.Token(SyntaxKind.VirtualKeyword))) .WithParameterList(F.ParameterList(parameterList)) .WithBody(F.Block(ThrowMockMissingStatement("VirtualIndexerSet")))); }
/// <summary> /// Returns the default table name that would be used for this entity type. /// </summary> /// <param name="entityType"> The entity type to get the table name for. </param> /// <returns> The default name of the table to which the entity type would be mapped. </returns> public static string GetDefaultTableName([NotNull] this IEntityType entityType) { var ownership = entityType.FindOwnership(); if (ownership != null && ownership.IsUnique) { return(ownership.PrincipalEntityType.GetTableName()); } return(Uniquifier.Truncate( entityType.HasDefiningNavigation() ? $"{entityType.DefiningEntityType.GetTableName()}_{entityType.DefiningNavigationName}" : entityType.ShortName(), entityType.Model.GetMaxIdentifierLength())); }
private MocklisTypesForSymbols(SemanticModel semanticModel, ClassDeclarationSyntax classDeclaration, MocklisSymbols mocklisSymbols, INamedTypeSymbol classSymbol, IMethodSymbol methodSymbol, bool nullableContextEnabled) { _semanticModel = semanticModel; _classDeclaration = classDeclaration; _mocklisSymbols = mocklisSymbols; _typeParameterNameSubstitutions = new Dictionary <string, string>(); _nullableContextEnabled = nullableContextEnabled; Uniquifier t = new Uniquifier(classSymbol.TypeParameters.Select(tp => tp.Name)); foreach (var methodTypeParameter in methodSymbol.TypeParameters) { string uniqueName = t.GetUniqueName(methodTypeParameter.Name); _typeParameterNameSubstitutions[methodTypeParameter.Name] = uniqueName; } }
/// <summary> /// Returns the default constraint name that would be used for this foreign key. /// </summary> /// <param name="foreignKey"> The foreign key. </param> /// <param name="tableName"> The table name. </param> /// <param name="schema"> The schema. </param> /// <param name="principalTableName"> The principal table name. </param> /// <param name="principalSchema"> The principal schema. </param> /// <returns> The default constraint name that would be used for this foreign key. </returns> public static string GetDefaultName( [NotNull] this IForeignKey foreignKey, [NotNull] string tableName, [CanBeNull] string schema, [NotNull] string principalTableName, [CanBeNull] string principalSchema) { var storeObject = StoreObjectIdentifier.Table(tableName, schema); var propertyNames = foreignKey.Properties.Select(p => p.GetColumnName(storeObject)).ToList(); var principalPropertyNames = foreignKey.PrincipalKey.Properties.Select(p => p.GetColumnName(storeObject)).ToList(); 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 => principalTableName == k.PrincipalEntityType.GetTableName() && principalSchema == k.PrincipalEntityType.GetSchema() && propertyNames.SequenceEqual(k.Properties.Select(p => p.GetColumnName(storeObject))) && principalPropertyNames.SequenceEqual(k.PrincipalKey.Properties.Select(p => p.GetColumnName(storeObject)))); if (linkedForeignKey == null) { break; } rootForeignKey = linkedForeignKey; } if (rootForeignKey != foreignKey) { return(rootForeignKey.GetConstraintName(tableName, schema, principalTableName, principalSchema)); } var baseName = new StringBuilder() .Append("FK_") .Append(tableName) .Append("_") .Append(principalTableName) .Append("_") .AppendJoin(foreignKey.Properties.Select(p => p.GetColumnName(storeObject)), "_") .ToString(); return(Uniquifier.Truncate(baseName, foreignKey.DeclaringEntityType.Model.GetMaxIdentifierLength())); }
static CloudBlockBlob GetUniqueBlobName(string uploadedFileName, FileInfo fileInfo, CloudBlobContainer container) { var length = fileInfo.Length; var packageBlob = Uniquifier.UniquifyUntil( uploadedFileName, container.GetBlockBlobReference, blob => { if (blob.Exists() && blob.Properties.Length != length) { Log.Verbose("A blob named " + blob.Name + " already exists but has a different length."); return(true); } return(false); }); return(packageBlob); }
/// <summary> /// Returns the default key constraint name that would be used for this key. /// </summary> /// <param name="key"> The key. </param> /// <returns> The default key constraint name that would be used for this key. </returns> public static string GetDefaultName([NotNull] this IKey key) { string name = null; var tableName = key.DeclaringEntityType.GetTableName(); if (key.IsPrimaryKey()) { name = "PK_" + tableName; } else { name = new StringBuilder() .Append("AK_") .Append(tableName) .Append("_") .AppendJoin(key.Properties.Select(p => p.GetColumnName()), "_") .ToString(); } return(Uniquifier.Truncate(name, key.DeclaringEntityType.Model.GetMaxIdentifierLength())); }
/// <inheritdoc /> public virtual void ProcessModelFinalizing(IConventionModelBuilder modelBuilder, IConventionContext <IConventionModelBuilder> context) { var model = modelBuilder.Metadata; var modelSequences = (SortedDictionary <(string Name, string Schema), Sequence>)model[RelationalAnnotationNames.Sequences]; if (modelSequences != null) { var maxLength = model.GetMaxIdentifierLength(); var toReplace = modelSequences .Where(s => s.Key.Name.Length > maxLength).ToList(); foreach (var sequence in toReplace) { var schemaName = sequence.Key.Schema; var newSequenceName = Uniquifier.Uniquify( sequence.Key.Name, modelSequences, sequenceName => (sequenceName, schemaName), maxLength); Sequence.SetName((IMutableModel)model, sequence.Value, newSequenceName); } } }
private static ForeignKey CreateSkipNavigationForeignKey( SkipNavigation skipNavigation, InternalEntityTypeBuilder associationEntityTypeBuilder) { var principalEntityType = skipNavigation.DeclaringEntityType; var principalKey = principalEntityType.FindPrimaryKey(); if (principalKey == null) { return(null); } var dependentEndForeignKeyPropertyNames = new List <string>(); var otherIdentifiers = associationEntityTypeBuilder.Metadata .GetDeclaredProperties().ToDictionary(p => p.Name, p => 0); foreach (var property in principalKey.Properties) { var propertyName = Uniquifier.Uniquify( string.Format( AssociationPropertyNameTemplate, principalEntityType.ShortName(), property.Name), otherIdentifiers, int.MaxValue); dependentEndForeignKeyPropertyNames.Add(propertyName); otherIdentifiers.Add(propertyName, 0); } return(associationEntityTypeBuilder .HasRelationship( principalEntityType.Name, dependentEndForeignKeyPropertyNames, principalKey, ConfigurationSource.Convention) .IsUnique(false, ConfigurationSource.Convention) .Metadata); }
/// <summary> /// Returns the default table name that would be used for this entity type. /// </summary> /// <param name="entityType"> The entity type to get the table name for. </param> /// <param name="truncate"> A value indicating whether the name should be truncated to the max identifier length. </param> /// <returns> The default name of the table to which the entity type would be mapped. </returns> public static string GetDefaultTableName([NotNull] this IEntityType entityType, bool truncate = true) { var ownership = entityType.FindOwnership(); if (ownership != null && ownership.IsUnique) { return(ownership.PrincipalEntityType.GetTableName()); } var name = entityType.ShortName(); if (entityType.HasDefiningNavigation()) { var definingTypeName = entityType.DefiningEntityType.GetTableName(); name = definingTypeName != null ? $"{definingTypeName}_{entityType.DefiningNavigationName}" : $"{entityType.DefiningNavigationName}_{name}"; } return(truncate ? Uniquifier.Truncate(name, entityType.Model.GetMaxIdentifierLength()) : name); }
private void CreateAssociationEntityType( IConventionSkipNavigationBuilder skipNavigationBuilder) { var skipNavigation = (SkipNavigation)skipNavigationBuilder.Metadata; if (skipNavigation.AssociationEntityType != null) { return; } if (skipNavigation.ForeignKey != null || skipNavigation.TargetEntityType == skipNavigation.DeclaringEntityType || !skipNavigation.IsCollection) { // do not create the association entity type for a self-referencing // skip navigation, or for one that is already "in use" // (i.e. has its Foreign Key assigned). return; } var inverseSkipNavigation = skipNavigation.Inverse; if (inverseSkipNavigation == null || inverseSkipNavigation.ForeignKey != null || !inverseSkipNavigation.IsCollection) { // do not create the association entity type if // the inverse skip navigation is already "in use" // (i.e. has its Foreign Key assigned). return; } Check.DebugAssert(inverseSkipNavigation.Inverse == skipNavigation, "Inverse's inverse should be the original skip navigation"); var declaringEntityType = skipNavigation.DeclaringEntityType; var inverseEntityType = inverseSkipNavigation.DeclaringEntityType; var model = declaringEntityType.Model; // create the association entity type var associationEntityTypeName = string.Format( AssociationEntityTypeNameTemplate, declaringEntityType.ShortName(), inverseEntityType.ShortName()); if (model.FindEntityType(associationEntityTypeName) != null) { var otherIdentifiers = model.GetEntityTypes().ToDictionary(et => et.Name, et => 0); associationEntityTypeName = Uniquifier.Uniquify( associationEntityTypeName, otherIdentifiers, int.MaxValue); } var associationEntityTypeBuilder = model.Builder.SharedEntity( associationEntityTypeName, Model.DefaultPropertyBagType, ConfigurationSource.Convention); // Create left and right foreign keys from the outer entity types to // the association entity type and configure the skip navigations. // Roll back if any of this fails. var leftForeignKey = CreateSkipNavigationForeignKey(skipNavigation, associationEntityTypeBuilder); if (leftForeignKey == null) { model.Builder.HasNoEntityType( associationEntityTypeBuilder.Metadata, ConfigurationSource.Convention); return; } var rightForeignKey = CreateSkipNavigationForeignKey(inverseSkipNavigation, associationEntityTypeBuilder); if (rightForeignKey == null) { // Removing the association entity type will also remove // the leftForeignKey created above. model.Builder.HasNoEntityType( associationEntityTypeBuilder.Metadata, ConfigurationSource.Convention); return; } skipNavigation.Builder.HasForeignKey(leftForeignKey, ConfigurationSource.Convention); inverseSkipNavigation.Builder.HasForeignKey(rightForeignKey, ConfigurationSource.Convention); // Creating the primary key below also negates the need for an index on // the properties of leftForeignKey - that index is automatically removed. associationEntityTypeBuilder.PrimaryKey( leftForeignKey.Properties.Concat(rightForeignKey.Properties).ToList(), ConfigurationSource.Convention); }
/// <summary> /// Returns the default key constraint name that would be used for this key for a particular table. /// </summary> /// <param name="key"> The key. </param> /// <param name="storeObject"> The identifier of the containing store object. </param> /// <returns> The default key constraint name that would be used for this key. </returns> public static string GetDefaultName([NotNull] this IKey key, StoreObjectIdentifier storeObject) { string name = null; if (key.IsPrimaryKey()) { 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 linkingFk = rootKey.DeclaringEntityType.FindRowInternalForeignKeys(storeObject) .FirstOrDefault(); if (linkingFk == null) { break; } rootKey = linkingFk.PrincipalEntityType.FindPrimaryKey(); } if (rootKey != null && rootKey != key) { return(rootKey.GetName(storeObject)); } name = "PK_" + storeObject.Name; } else { var propertyNames = key.Properties.Select(p => p.GetColumnName(storeObject)).ToList(); 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 .FindRowInternalForeignKeys(storeObject) .SelectMany(fk => fk.PrincipalEntityType.GetKeys()) .FirstOrDefault(k => k.Properties.Select(p => p.GetColumnName(storeObject)).SequenceEqual(propertyNames)); if (linkedKey == null) { break; } rootKey = linkedKey; } if (rootKey != key) { return(rootKey.GetName(storeObject)); } name = new StringBuilder() .Append("AK_") .Append(storeObject.Name) .Append("_") .AppendJoin(key.Properties.Select(p => p.GetColumnName(storeObject)), "_") .ToString(); } return(Uniquifier.Truncate(name, key.DeclaringEntityType.Model.GetMaxIdentifierLength())); }
protected MemberDeclarationSyntax ExplicitInterfaceMember() { var baseReturnType = Symbol.ReturnsVoid ? F.PredefinedType(F.Token(SyntaxKind.VoidKeyword)) : TypesForSymbols.ParseTypeName(Symbol.ReturnType, Symbol.ReturnTypeIsNullableOrOblivious()); var returnType = baseReturnType; if (Symbol.ReturnsByRef) { returnType = F.RefType(returnType); } else if (Symbol.ReturnsByRefReadonly) { returnType = F.RefType(returnType).WithReadOnlyKeyword(F.Token(SyntaxKind.ReadOnlyKeyword)); } var mockedMethod = ExplicitInterfaceMemberMethodDeclaration(returnType); var memberMockInstance = ExplicitInterfaceMemberMemberMockInstance(); ExpressionSyntax invocation = F.InvocationExpression( F.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, memberMockInstance, F.IdentifierName("Call"))) .WithExpressionsAsArgumentList(ParametersType.BuildArgumentListWithOriginalNames()); // look at the return parameters. If we don't have any we can just make the call. // if we only have one and that's the return value, we can just return it. if (ReturnValuesType.Count == 0 || ReturnValuesType.Count == 1 && ReturnValuesType[0].IsReturnValue) { if (Symbol.ReturnsByRef || Symbol.ReturnsByRefReadonly) { invocation = TypesForSymbols.WrapByRef(invocation, baseReturnType); } mockedMethod = mockedMethod.WithExpressionBody(F.ArrowExpressionClause(invocation)) .WithSemicolonToken(F.Token(SyntaxKind.SemicolonToken)); } // if we only have one and that's not a return value, we can just assign it to the out or ref parameter it corresponds to. else if (ReturnValuesType.Count == 1) { mockedMethod = mockedMethod.WithBody(F.Block(F.ExpressionStatement(F.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, F.IdentifierName(ReturnValuesType[0].OriginalName), invocation)))); } else { // if we have more than one, put it in a temporary variable. (consider name clashes with method parameter names) var x = new Uniquifier(Symbol.Parameters.Select(m => m.Name)); string tmp = x.GetUniqueName("tmp"); var statements = new List <StatementSyntax> { F.LocalDeclarationStatement(F.VariableDeclaration(F.IdentifierName("var")).WithVariables( F.SingletonSeparatedList(F.VariableDeclarator(F.Identifier(tmp)).WithInitializer(F.EqualsValueClause(invocation))))) }; // then for any out or ref parameters, set their values from the temporary variable. foreach (var rv in ReturnValuesType.Where(a => !a.IsReturnValue)) { statements.Add(F.ExpressionStatement(F.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, F.IdentifierName(rv.OriginalName), F.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, F.IdentifierName(tmp), F.IdentifierName(rv.TupleSafeName))))); } // finally, if there is a 'proper' return type, return the corresponding value from the temporary variable. foreach (var rv in ReturnValuesType.Where(a => a.IsReturnValue)) { ExpressionSyntax memberAccess = F.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, F.IdentifierName(tmp), F.IdentifierName(rv.TupleSafeName)); if (Symbol.ReturnsByRef || Symbol.ReturnsByRefReadonly) { memberAccess = TypesForSymbols.WrapByRef(memberAccess, baseReturnType); } statements.Add(F.ReturnStatement(memberAccess)); } mockedMethod = mockedMethod.WithBody(F.Block(statements)); } return(mockedMethod); }