public static IIndex <TDatabase, TTable> Index <TDatabase, TTable>(this IIndexBuilder <TDatabase, TTable> @this, Expression <Func <IOrderFilter <TTable>, object> > keyColumns, bool unique = false, string name = null, bool clustered = false, Expression <Func <TTable, object> > includedColumns = null) { var builder = @this as InternalTableBuilder <TDatabase, TTable>; var indexKeyColumns = ExpressionHelpers.ParseOrderedMultiPropertySelector(keyColumns ?? throw ModelBuilderError.ArgumentNull(nameof(keyColumns)).AsException()).MatchColumns(builder.Name, builder.Columns); var indexIncludedColumns = includedColumns == null?ImmutableArray.Create <ColumnModel>() : ExpressionHelpers.ParseMultiPropertySelector(includedColumns).MatchColumns(builder.Name, builder.Columns); var indexName = name ?? BuilderHelper.GenerateKeyName("IX", builder.Schema, builder.Name, indexKeyColumns.Select(c => c.Name)); if (clustered) { var priorClustered = builder.PrimaryKey?.IsClustered == true ? builder.PrimaryKey.Name : builder.Indexes.FirstOrDefault(i => i.IsClustered)?.Name; if (priorClustered != null) { throw ModelBuilderError.IndexClusteredAlreadySpecified(priorClustered).AsException(); } } { var column = indexIncludedColumns.FirstOrDefault(i => indexKeyColumns.Any(k => k.Property.Name == i.Property.Name)); if (column != null) { throw ModelBuilderError.IndexIncludedColumnAlreadyInKeyColumns(column.Name).AsException(); } } builder.Indexes.Add(new IndexModel(name: indexName, keyColumns: indexKeyColumns.ToImmutableArray(), isUnique: unique, isClustered: clustered, includedColumns: indexIncludedColumns.ToImmutableArray())); return(builder); }
static FuzzyTableModel ParseTableIndex(SyntaxNodeAnalysisContext context, InvocationExpressionSyntax expression, FuzzyDatabaseModel partialDatabase) { var innerModel = ParseTableChain(context, expression, partialDatabase); var arguments = AH.ParseArguments(context, expression); var keyColumnsArg = arguments["keyColumns"]; var uniqueArg = arguments["unique"]; var nameArg = arguments["name"]; var clusteredArg = arguments["clustered"]; var includedColumnsArg = arguments["includedColumns"]; var keyColumns = new Optional <ImmutableArray <(SortOrder, FuzzyColumnModel)> >(); if (AH.IsNull(context, keyColumnsArg)) { context.ReportDiagnostic(BuilderError.ArgumentNull("keyColumns").MakeDiagnostic(keyColumnsArg.GetLocation())); } else { var props = AH.ParseOrderedMultiProperty(context, keyColumnsArg); if (props.HasValue) { keyColumns = AH.MatchColumns(context, props.Value, innerModel.Columns, ToString(innerModel.Name)); } } var includedColumns = new Optional <ImmutableArray <FuzzyColumnModel> >(); if (!AH.IsNull(context, includedColumnsArg)) { var props = AH.ParseMultiProperty(context, includedColumnsArg); if (props.HasValue) { var match = AH.MatchColumns(context, props.Value, innerModel.Columns, ToString(innerModel.Name)); includedColumns = match.HasValue ? AH.Just(match.Value.Select(m => m.Item1).ToImmutableArray()) : new Optional <ImmutableArray <FuzzyColumnModel> >(); if (keyColumns.HasValue) { var column = props.Value.Select(v => ((FuzzyProperty, Location)?)v) .FirstOrDefault(i => keyColumns.Value.Any(k => k.Item2.Property.HasValue && k.Item2.Property.Value.Name == i.Value.Item1.Name)); if (column != null) { context.ReportDiagnostic(ModelBuilderError.IndexIncludedColumnAlreadyInKeyColumns(column.Value.Item1.Name).MakeDiagnostic(column.Value.Item2)); } } } } var fuzzyIndex = new FuzzyIndexModel() { KeyColumns = keyColumns, IsUnique = AH.ParseConstantArgument(context, uniqueArg, () => AH.Just(false)), IsClustered = AH.ParseConstantArgument(context, clusteredArg, () => AH.Just(false)), IncludedColumns = includedColumns, Name = AH.ParseConstantArgument(context, nameArg, () => (!innerModel.Name.HasValue || !innerModel.Schema.HasValue || !keyColumns.HasValue || keyColumns.Value.Any(c => !c.Item2.Name.HasValue)) ? new Optional <string>() : AH.Just(BuildDefaultKeyName("IX", innerModel.Schema.Value, innerModel.Name.Value, keyColumns.Value.Select(c => c.Item2.Name.Value)))) }; if (fuzzyIndex.IsClustered.HasValue && fuzzyIndex.IsClustered.Value == true) { var priorClustered = (innerModel.PrimaryKey?.IsClustered)?.HasValue == true && innerModel.PrimaryKey.IsClustered.Value ? innerModel.PrimaryKey.Name.Value : innerModel.Indexes.FirstOrDefault(i => i.IsClustered.HasValue && i.IsClustered.Value)?.Name.Value; if (priorClustered != null) { context.ReportDiagnostic(ModelBuilderError.IndexClusteredAlreadySpecified(priorClustered).MakeDiagnostic(clusteredArg.Expression.GetLocation())); } } innerModel.Indexes.Add(fuzzyIndex); return(innerModel); }
public async void Error_On_Clustered_When_Previous_Index_Or_Primary_Key_Clustered(string location, string indexName, string index) { await VerifyIndexErrorRaised(ModelBuilderError.IndexClusteredAlreadySpecified(indexName), location, index); }