From 0d306a8363ffca6eab5de91556ae7304d0c42371 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Fri, 13 Feb 2026 20:39:35 +0100 Subject: [PATCH] Document SQL Server full-text catalog/index creation See https://github.com/dotnet/efcore/issues/11488 --- .../providers/sql-server/full-text-search.md | 78 ++++++++++++++++++- .../core/what-is-new/ef-core-11.0/whatsnew.md | 29 ++++++- 2 files changed, 101 insertions(+), 6 deletions(-) diff --git a/entity-framework/core/providers/sql-server/full-text-search.md b/entity-framework/core/providers/sql-server/full-text-search.md index 98ffe7b2bc..54153a9fe7 100644 --- a/entity-framework/core/providers/sql-server/full-text-search.md +++ b/entity-framework/core/providers/sql-server/full-text-search.md @@ -13,12 +13,82 @@ EF Core's SQL Server provider supports both full-text search *predicates* (for f ## Setting up full-text search -Before using full-text search, you must: +Before using full-text search, you must create a [full-text catalog](/sql/t-sql/statements/create-fulltext-catalog-transact-sql) on your database, and a [full-text index](/sql/t-sql/statements/create-fulltext-index-transact-sql) on the columns you want to search. -1. **Create a full-text catalog** on your database -2. **Create a full-text index** on the columns you want to search +### [EF Core 11+](#tab/ef-core-11) -This setup is done at the SQL Server level and is outside the scope of EF Core. For more information, see the [SQL Server full-text search documentation](/sql/relational-databases/search/get-started-with-full-text-search). +> [!NOTE] +> Full-text catalog and index management in migrations was introduced in EF Core 11. + +You can configure full-text catalogs and indexes directly in your EF model. When you add a [migration](xref:core/managing-schemas/migrations/index), EF will generate the appropriate SQL to create (or alter) the catalog and index for you. + +First, define a full-text catalog on the model, then configure a full-text index on your entity type: + +```csharp +protected override void OnModelCreating(ModelBuilder modelBuilder) +{ + modelBuilder.HasFullTextCatalog("ftCatalog"); + + modelBuilder.Entity
() + .HasFullTextIndex(a => a.Contents) + .HasKeyIndex("PK_Articles") + .OnCatalog("ftCatalog"); +} +``` + +The `HasKeyIndex()` method specifies the unique, non-nullable, single-column index used as the full-text key for the table (typically the primary key index). `OnCatalog()` assigns the full-text index to a specific catalog. + +You can also configure multiple columns and additional options such as per-column languages and change tracking: + +```csharp +modelBuilder.Entity
() + .HasFullTextIndex(a => new { a.Title, a.Contents }) + .HasKeyIndex("PK_Articles") + .OnCatalog("ftCatalog") + .WithChangeTracking(FullTextChangeTracking.Manual) + .HasLanguage("Title", "English") + .HasLanguage("Contents", "French"); +``` + +The full-text catalog can also be configured as the default catalog, and with accent sensitivity: + +```csharp +modelBuilder.HasFullTextCatalog("ftCatalog") + .IsDefault() + .IsAccentSensitive(false); +``` + +### [Older versions](#tab/older-versions) + +On older versions of EF Core, you can set up full-text search by adding raw SQL to a migration. Add an empty migration and then edit it to include the full-text catalog and index creation SQL: + +```csharp +protected override void Up(MigrationBuilder migrationBuilder) +{ + migrationBuilder.Sql( + sql: "CREATE FULLTEXT CATALOG ftCatalog AS DEFAULT;", + suppressTransaction: true); + + migrationBuilder.Sql( + sql: "CREATE FULLTEXT INDEX ON Articles(Contents) KEY INDEX PK_Articles;", + suppressTransaction: true); +} + +protected override void Down(MigrationBuilder migrationBuilder) +{ + migrationBuilder.Sql( + sql: "DROP FULLTEXT INDEX ON Articles;", + suppressTransaction: true); + + migrationBuilder.Sql( + sql: "DROP FULLTEXT CATALOG ftCatalog;", + suppressTransaction: true); +} +``` + +--- + +For more information, see the [SQL Server full-text search documentation](/sql/relational-databases/search/get-started-with-full-text-search). ## Full-text predicates diff --git a/entity-framework/core/what-is-new/ef-core-11.0/whatsnew.md b/entity-framework/core/what-is-new/ef-core-11.0/whatsnew.md index 6519a37ce9..a6c8aa1b4c 100644 --- a/entity-framework/core/what-is-new/ef-core-11.0/whatsnew.md +++ b/entity-framework/core/what-is-new/ef-core-11.0/whatsnew.md @@ -260,9 +260,34 @@ This translates to the SQL Server [`VECTOR_SEARCH()`](/sql/t-sql/functions/vecto For more information, see the [full documentation on vector search](xref:core/providers/sql-server/vector-search). - + -### Full-text search table-valued functions +### Full-text search improvements + +#### Full-text search catalog and index creation + +SQL Server's [full-text search](/sql/relational-databases/search/full-text-search) requires a full-text catalog and index to be set up on your database before you can use it. EF 11 now allows configuring full-text catalogs and indexes in your model, so that [EF migrations](xref:core/managing-schemas/migrations/index) can automatically create and manage them for you: + +```csharp +// In your OnModelCreating: +modelBuilder.HasFullTextCatalog("ftCatalog"); + +modelBuilder.Entity() + .HasFullTextIndex(b => b.FullName) + .HasKeyIndex("PK_Blogs") + .OnCatalog("ftCatalog"); +``` + +This generates the following SQL in a migration: + +```sql +CREATE FULLTEXT CATALOG [ftCatalog]; +CREATE FULLTEXT INDEX ON [Blogs]([FullName]) KEY INDEX [PK_Blogs] ON [ftCatalog]; +``` + +Previously, full-text catalog and index creation had to be managed manually by adding SQL to migrations. For full details on setting up full-text catalogs and indexes, see the [full-text search documentation](xref:core/providers/sql-server/full-text-search#setting-up-full-text-search). + +#### Full-text search table-valued functions EF Core has long provided support for SQL Server's full-text search predicates `FREETEXT()` and `CONTAINS()`, via `EF.Functions.FreeText()` and `EF.Functions.Contains()`. These predicates can be used in LINQ `Where()` clauses to filter results based on search criteria.