From 66c103954f4326e187b75f1f45440ea02e364abd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 17 Jun 2026 22:54:49 +0000 Subject: [PATCH 1/3] Initial plan From 5a33270cba4be517f8b98be40a179efebf9a5704 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 17 Jun 2026 23:00:34 +0000 Subject: [PATCH 2/3] Add validation for unsupported options on full-text/vector indexes Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com> --- .../Internal/SqlServerModelValidator.cs | 31 +++++++++++++++++++ .../Properties/SqlServerStrings.Designer.cs | 16 ++++++++++ .../Properties/SqlServerStrings.resx | 6 ++++ 3 files changed, 53 insertions(+) diff --git a/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerModelValidator.cs b/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerModelValidator.cs index 05847aba234..9f5255705df 100644 --- a/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerModelValidator.cs +++ b/src/EFCore.SqlServer/Infrastructure/Internal/SqlServerModelValidator.cs @@ -325,6 +325,10 @@ protected virtual void ValidateFullTextIndex( var entityType = index.DeclaringEntityType; + ValidateUnsupportedIndexOptions( + index, + (option) => SqlServerStrings.FullTextIndexUnsupportedOption(index.DisplayName(), entityType.DisplayName(), option)); + if (++_entityFullTextIndexCount > 1) { throw new InvalidOperationException( @@ -384,6 +388,11 @@ protected virtual void ValidateVectorIndex(IIndex index) { if (index.IsVectorIndex()) { + ValidateUnsupportedIndexOptions( + index, + (option) => SqlServerStrings.VectorIndexUnsupportedOption( + index.DisplayName(), index.DeclaringEntityType.DisplayName(), option)); + if (index.Properties is not [var propertyBase]) { throw new InvalidOperationException( @@ -420,6 +429,28 @@ protected virtual void ValidateVectorIndex(IIndex index) } } + private static void ValidateUnsupportedIndexOptions(IIndex index, Func errorFactory) + { + var option = index switch + { + { IsUnique: true } => nameof(index.IsUnique), + { IsDescending: not null } => nameof(index.IsDescending), + _ when index.GetFilter() is not null => "Filter", + _ when index.IsClustered() is not null => "IsClustered", + _ when index.GetIncludeProperties() is not null => "IncludeProperties", + _ when index.GetFillFactor() is not null => "FillFactor", + _ when index.IsCreatedOnline() is not null => "IsCreatedOnline", + _ when index.GetSortInTempDb() is not null => "SortInTempDb", + _ when index.GetDataCompression() is not null => "DataCompression", + _ => null + }; + + if (option is not null) + { + throw new InvalidOperationException(errorFactory(option)); + } + } + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in diff --git a/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs b/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs index 590cdd70008..ccf102d7c12 100644 --- a/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs +++ b/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs @@ -199,6 +199,14 @@ public static string FullTextIndexOnInvalidColumn(object? index, object? entityT GetString("FullTextIndexOnInvalidColumn", nameof(index), nameof(entityType), nameof(property)), index, entityType, property); + /// + /// Full-text index '{index}' on entity type '{entityType}' was configured with the '{option}' option, which is not supported on full-text indexes. + /// + public static string FullTextIndexUnsupportedOption(object? index, object? entityType, object? option) + => string.Format( + GetString("FullTextIndexUnsupportedOption", nameof(index), nameof(entityType), nameof(option)), + index, entityType, option); + /// /// Multiple full-text catalogs are marked as default. Only one full-text catalog can be the default. /// @@ -551,6 +559,14 @@ public static string VectorIndexRequiresType(object? index, object? entityType) GetString("VectorIndexRequiresType", nameof(index), nameof(entityType)), index, entityType); + /// + /// Vector index '{index}' on entity type '{entityType}' was configured with the '{option}' option, which is not supported on vector indexes. + /// + public static string VectorIndexUnsupportedOption(object? index, object? entityType, object? option) + => string.Format( + GetString("VectorIndexUnsupportedOption", nameof(index), nameof(entityType), nameof(option)), + index, entityType, option); + /// /// Vector property '{propertyName}' is on '{structuralType}' which is mapped to JSON. Vector properties are not supported within JSON documents. /// diff --git a/src/EFCore.SqlServer/Properties/SqlServerStrings.resx b/src/EFCore.SqlServer/Properties/SqlServerStrings.resx index d4d2d53cbe8..b7df6626971 100644 --- a/src/EFCore.SqlServer/Properties/SqlServerStrings.resx +++ b/src/EFCore.SqlServer/Properties/SqlServerStrings.resx @@ -186,6 +186,9 @@ Full-text index '{index}' on entity type '{entityType}' includes property '{property}' which is not mapped to a text or varbinary column type supported by full-text search. + + Full-text index '{index}' on entity type '{entityType}' was configured with the '{option}' option, which is not supported on full-text indexes. + Multiple full-text catalogs are marked as default. Only one full-text catalog can be the default. @@ -427,6 +430,9 @@ Vector index '{index}' on entity type '{entityType}' cannot have an empty vector index type. + + Vector index '{index}' on entity type '{entityType}' was configured with the '{option}' option, which is not supported on vector indexes. + Vector property '{propertyName}' is on '{structuralType}' which is mapped to JSON. Vector properties are not supported within JSON documents. From 4c875c797d41c241c672a95710faa3b28000ada9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 17 Jun 2026 23:04:58 +0000 Subject: [PATCH 3/3] Add tests for unsupported full-text/vector index options Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com> --- .../SqlServerModelValidatorTest.cs | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/test/EFCore.SqlServer.Tests/Infrastructure/SqlServerModelValidatorTest.cs b/test/EFCore.SqlServer.Tests/Infrastructure/SqlServerModelValidatorTest.cs index edef1a608f3..cb45b243db8 100644 --- a/test/EFCore.SqlServer.Tests/Infrastructure/SqlServerModelValidatorTest.cs +++ b/test/EFCore.SqlServer.Tests/Infrastructure/SqlServerModelValidatorTest.cs @@ -1373,6 +1373,28 @@ public virtual void Throws_for_vector_index_on_non_vector_property() modelBuilder); } + [Fact] + [Experimental("EF9105")] + public virtual void Throws_for_vector_index_with_unsupported_option() + { + var modelBuilder = CreateConventionModelBuilder(); + + modelBuilder.Entity( + b => + { + b.Property(e => e.Vector).HasMaxLength(3); + var indexBuilder = b.HasVectorIndex(e => e.Vector).HasMetric("cosine"); + indexBuilder.Metadata.SetDataCompression(DataCompressionType.Page); + }); + + VerifyError( + SqlServerStrings.VectorIndexUnsupportedOption( + "{'Vector'}", + nameof(VectorWithoutDimensionsEntity), + "DataCompression"), + modelBuilder); + } + public class VectorWithoutDimensionsEntity { public int Id { get; set; } @@ -1551,6 +1573,25 @@ public virtual void Throws_for_full_text_index_with_mixed_valid_and_invalid_colu modelBuilder); } + [Fact] + public virtual void Throws_for_full_text_index_with_unsupported_option() + { + var modelBuilder = CreateConventionModelBuilder(); + + modelBuilder.Entity(b => + { + var indexBuilder = b.HasFullTextIndex(e => e.Title).UseKeyIndex("PK_FullTextEntityValid"); + indexBuilder.Metadata.IsUnique = true; + }); + + VerifyError( + SqlServerStrings.FullTextIndexUnsupportedOption( + "{'Title'}", + nameof(FullTextEntityValid), + "IsUnique"), + modelBuilder); + } + public class FullTextEntityWithTwoIndexes { public int Id { get; set; }