Skip to content

Commit 6100458

Browse files
authored
feat(templates): add sql server based vector search support to bit Boilerplate #11011 (#11012)
1 parent 2db9f58 commit 6100458

File tree

13 files changed

+84
-35
lines changed

13 files changed

+84
-35
lines changed

src/Templates/Boilerplate/Bit.Boilerplate/.template.config/template.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,7 @@
488488
]
489489
},
490490
{
491-
"condition": "(signalR != true && database != PostgreSQL)",
491+
"condition": "(signalR != true && database != PostgreSQL && database != SqlServer)",
492492
"exclude": [
493493
"src/Server/Boilerplate.Server.Api/Services/ProductEmbeddingService.cs"
494494
]
@@ -520,7 +520,7 @@
520520
]
521521
},
522522
{
523-
"condition": "(signalR != true && notification != PostgreSQL)",
523+
"condition": "(signalR != true && notification != true)",
524524
"exclude": [
525525
"src/Shared/Boilerplate.Shared/Dtos/Identity/SendNotificationToRoleDto.cs"
526526
]

src/Templates/Boilerplate/Bit.Boilerplate/src/Directory.Packages.props

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,14 @@
6262
<PackageVersion Condition=" '$(offlineDb)' == 'true' OR '$(offlineDb)' == ''" Include="Bit.Besql" Version="9.9.2" />
6363
<PackageVersion Condition=" '$(signalR)' == 'true' OR '$(signalR)' == ''" Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.6" />
6464
<PackageVersion Condition=" '$(signalR)' == 'true' OR '$(signalR)' == ''" Include="Microsoft.Azure.SignalR" Version="1.30.3" />
65-
<PackageVersion Condition=" ('$(signalR)' == 'true' OR '$(signalR)' == '') OR ('$(database)' == 'PostgreSQL' OR '$(database)' == '') " Include="Microsoft.Extensions.AI" Version="9.6.0" />
66-
<PackageVersion Condition=" ('$(signalR)' == 'true' OR '$(signalR)' == '') OR ('$(database)' == 'PostgreSQL' OR '$(database)' == '') " Include="Microsoft.Extensions.AI.OpenAI" Version="9.6.0-preview.1.25310.2" />
67-
<PackageVersion Condition=" ('$(signalR)' == 'true' OR '$(signalR)' == '') OR ('$(database)' == 'PostgreSQL' OR '$(database)' == '') " Include="Microsoft.Extensions.AI.AzureAIInference" Version="9.6.0-preview.1.25310.2" />
65+
<PackageVersion Condition=" ('$(signalR)' == 'true' OR '$(signalR)' == '') OR ('$(database)' == 'PostgreSQL' OR '$(database)' == '') OR ('$(database)' == 'SqlServer' OR '$(database)' == '') " Include="Microsoft.Extensions.AI" Version="9.6.0" />
66+
<PackageVersion Condition=" ('$(signalR)' == 'true' OR '$(signalR)' == '') OR ('$(database)' == 'PostgreSQL' OR '$(database)' == '') OR ('$(database)' == 'SqlServer' OR '$(database)' == '') " Include="Microsoft.Extensions.AI.OpenAI" Version="9.6.0-preview.1.25310.2" />
67+
<PackageVersion Condition=" ('$(signalR)' == 'true' OR '$(signalR)' == '') OR ('$(database)' == 'PostgreSQL' OR '$(database)' == '') OR ('$(database)' == 'SqlServer' OR '$(database)' == '') " Include="Microsoft.Extensions.AI.AzureAIInference" Version="9.6.0-preview.1.25310.2" />
6868
<PackageVersion Condition=" ('$(database)' == 'PostgreSQL' OR '$(database)' == '') " Include="Pgvector.EntityFrameworkCore" Version="0.2.2" />
6969
<PackageVersion Condition="'$(module)' == 'Admin' OR '$(module)' == ''" Include="Newtonsoft.Json" Version="13.0.3" />
7070
<PackageVersion Condition=" '$(appInsights)' == 'true' OR '$(appInsights)' == '' " Include="Microsoft.Extensions.Logging.ApplicationInsights" Version="2.23.0" />
7171
<PackageVersion Condition=" '$(appInsights)' == 'true' OR '$(appInsights)' == '' " Include="BlazorApplicationInsights" Version="3.2.1" />
72+
<PackageVersion Condition=" '$(database)' == 'SqlServer' OR '$(database)' == '' " Include="EFCore.SqlServer.VectorSearch" Version="9.0.0-preview.2" />
7273
<PackageVersion Condition=" '$(database)' == 'SqlServer' OR '$(database)' == '' " Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.6" />
7374
<PackageVersion Condition=" '$(database)' == 'PostgreSQL' OR '$(database)' == '' " Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
7475
<PackageVersion Condition=" '$(database)' == 'MySql' OR '$(database)' == '' " Include="Pomelo.EntityFrameworkCore.MySql" Version="9.0.0-preview.2.efcore.9.0.0" />

src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Boilerplate.Server.Api.csproj

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
<PackageReference Include="Microsoft.AspNetCore.OData" />
4242
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" PrivateAssets="all" />
4343
<PackageReference Include="Microsoft.EntityFrameworkCore" />
44+
<PackageReference Condition=" '$(database)' == 'SqlServer' OR '$(database)' == '' " Include="EFCore.SqlServer.VectorSearch" />
4445
<PackageReference Condition=" '$(database)' == 'SqlServer' OR '$(database)' == '' " Include="Microsoft.EntityFrameworkCore.SqlServer" />
4546
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" />
4647
<PackageReference Condition=" '$(database)' == 'PostgreSQL' OR '$(database)' == '' " Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
@@ -57,9 +58,9 @@
5758
<PackageReference Include="Riok.Mapperly" />
5859
<PackageReference Include="Twilio" />
5960
<PackageReference Condition=" '$(notification)' == 'true' OR '$(notification)' == ''" Include="AdsPush" />
60-
<PackageReference Condition=" ('$(signalR)' == 'true' OR '$(signalR)' == '') OR ('$(database)' == 'PostgreSQL' OR '$(database)' == '') " Include="Microsoft.Extensions.AI" />
61-
<PackageReference Condition=" ('$(signalR)' == 'true' OR '$(signalR)' == '') OR ('$(database)' == 'PostgreSQL' OR '$(database)' == '') " Include="Microsoft.Extensions.AI.AzureAIInference" />
62-
<PackageReference Condition=" ('$(signalR)' == 'true' OR '$(signalR)' == '') OR ('$(database)' == 'PostgreSQL' OR '$(database)' == '') " Include="Microsoft.Extensions.AI.OpenAI" />
61+
<PackageReference Condition=" ('$(signalR)' == 'true' OR '$(signalR)' == '') OR ('$(database)' == 'PostgreSQL' OR '$(database)' == '') OR ('$(database)' == 'SqlServer' OR '$(database)' == '') " Include="Microsoft.Extensions.AI" />
62+
<PackageReference Condition=" ('$(signalR)' == 'true' OR '$(signalR)' == '') OR ('$(database)' == 'PostgreSQL' OR '$(database)' == '') OR ('$(database)' == 'SqlServer' OR '$(database)' == '') " Include="Microsoft.Extensions.AI.AzureAIInference" />
63+
<PackageReference Condition=" ('$(signalR)' == 'true' OR '$(signalR)' == '') OR ('$(database)' == 'PostgreSQL' OR '$(database)' == '') OR ('$(database)' == 'SqlServer' OR '$(database)' == '') " Include="Microsoft.Extensions.AI.OpenAI" />
6364
<PackageReference Condition=" ('$(database)' == 'PostgreSQL' OR '$(database)' == '') " Include="Pgvector.EntityFrameworkCore" />
6465

6566
<Using Include="Microsoft.EntityFrameworkCore.Migrations" />
@@ -76,7 +77,7 @@
7677
<Using Include="Microsoft.AspNetCore.OData.Query" />
7778
<Using Include="Microsoft.AspNetCore.Mvc" />
7879

79-
<Using Condition=" ('$(signalR)' == 'true' OR '$(signalR)' == '') OR ('$(database)' == 'PostgreSQL' OR '$(database)' == '') " Include="Microsoft.Extensions.AI" />
80+
<Using Condition=" ('$(signalR)' == 'true' OR '$(signalR)' == '') OR ('$(database)' == 'PostgreSQL' OR '$(database)' == '') OR ('$(database)' == 'SqlServer' OR '$(database)' == '') " Include="Microsoft.Extensions.AI" />
8081
<Using Condition=" '$(signalR)' == 'true' OR '$(signalR)' == ''" Include="Boilerplate.Server.Api.Models.Chatbot" />
8182
<Content Include="..\..\..\Bit.ResxTranslator.json" Link="Resources\Bit.ResxTranslator.json" />
8283

src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Controllers/AttachmentController.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public partial class AttachmentController : AppControllerBase, IAttachmentContro
1919
[AutoInject] private IBlobStorage blobStorage = default!;
2020
[AutoInject] private UserManager<User> userManager = default!;
2121

22-
//#if (signalR == true || database == "PostgreSQL")
22+
//#if (signalR == true || database == "PostgreSQL" || database == "SqlServer")
2323
[AutoInject] private IServiceProvider serviceProvider = default!;
2424
[AutoInject] private ILogger<AttachmentController> logger = default!;
2525
//#endif
@@ -200,7 +200,7 @@ private async Task<IActionResult> UploadAttachment(Guid attachmentId, Attachment
200200
//#if (module == "Sales" || module == "Admin")
201201
if (attachment.Kind is AttachmentKind.ProductPrimaryImageMedium)
202202
{
203-
//#if (signalR == true || database == "PostgreSQL")
203+
//#if (signalR == true || database == "PostgreSQL" || database == "SqlServer")
204204
if (serviceProvider.GetService<IChatClient>() is IChatClient chatClient)
205205
{
206206
string responseText = (await chatClient.GetResponseAsync([

src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Controllers/Products/ProductController.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public partial class ProductController : AppControllerBase, IProductController
2121
//#if (signalR == true)
2222
[AutoInject] private IHubContext<AppHub> appHubContext = default!;
2323
//#endif
24-
//#if (signalR == true || database == "PostgreSQL")
24+
//#if (signalR == true || database == "PostgreSQL" || database == "SqlServer")
2525
[AutoInject] private ProductEmbeddingService productEmbeddingService = default!;
2626
//#endif
2727
[AutoInject] private ResponseCacheService responseCacheService = default!;
@@ -49,7 +49,7 @@ public async Task<PagedResult<ProductDto>> GetProducts(ODataQueryOptions<Product
4949
[HttpGet("{searchQuery}")]
5050
public async Task<PagedResult<ProductDto>> GetProductsBySearchQuery(string searchQuery, ODataQueryOptions<ProductDto> odataQuery, CancellationToken cancellationToken)
5151
{
52-
//#if (database == "PostgreSQL")
52+
//#if (database == "PostgreSQL" || database == "SqlServer")
5353
var query = (IQueryable<ProductDto>)odataQuery.ApplyTo((await (productEmbeddingService.GetProductsBySearchQuery(searchQuery, cancellationToken))).Project(),
5454
ignoreQueryOptions: AllowedQueryOptions.Top | AllowedQueryOptions.Skip | AllowedQueryOptions.OrderBy /* Ordering can disrupt the results of the embedding service. */);
5555
var totalCount = await query.LongCountAsync(cancellationToken);
@@ -85,9 +85,10 @@ public async Task<ProductDto> Create(ProductDto dto, CancellationToken cancellat
8585

8686
await Validate(entityToAdd, cancellationToken);
8787

88-
//#if (database == "PostgreSQL" || signalR == true)
88+
//#if (database == "PostgreSQL" || database == "SqlServer" || signalR == true)
8989
//#if (IsInsideProjectTemplate == true)
90-
if (DbContext.Database.ProviderName!.EndsWith("PostgreSQL", StringComparison.InvariantCulture) is false)
90+
if (DbContext.Database.ProviderName!.EndsWith("PostgreSQL", StringComparison.InvariantCulture) ||
91+
DbContext.Database.ProviderName!.EndsWith("SqlServer", StringComparison.InvariantCulture))
9192
{
9293
//#endif
9394
await productEmbeddingService.Embed(entityToAdd, cancellationToken);
@@ -117,9 +118,10 @@ public async Task<ProductDto> Update(ProductDto dto, CancellationToken cancellat
117118

118119
await Validate(entityToUpdate, cancellationToken);
119120

120-
//#if (database == "PostgreSQL" || signalR == true)
121+
//#if (database == "PostgreSQL" || database == "SqlServer" || signalR == true)
121122
//#if (IsInsideProjectTemplate == true)
122-
if (DbContext.Database.ProviderName!.EndsWith("PostgreSQL", StringComparison.InvariantCulture) is false)
123+
if (DbContext.Database.ProviderName!.EndsWith("PostgreSQL", StringComparison.InvariantCulture) ||
124+
DbContext.Database.ProviderName!.EndsWith("SqlServer", StringComparison.InvariantCulture))
123125
{
124126
//#endif
125127
await productEmbeddingService.Embed(entityToUpdate, cancellationToken);

src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Data/AppDbContext.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
5656
{
5757
//#endif
5858
//#if (database == "PostgreSQL")
59-
if (EmbeddingIsEnabled)
59+
if (IsEmbeddingEnabled)
6060
{
6161
modelBuilder.HasPostgresExtension("vector");
6262
}
@@ -266,10 +266,14 @@ private void ConfigureConcurrencyStamp(ModelBuilder modelBuilder)
266266
}
267267
}
268268

269+
//#if (database == "PostgreSQL" || database == "SqlServer")
269270
//#if (database == "PostgreSQL")
270271
// In order to enable embedding, the `pgvector` extension must be installed in your PostgreSQL.
271272
// The following command runs the postgreSQL container with the `pgvector` extension:
272273
// docker run -d --name postgres -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=BoilerplateDb -p 5432:5432 -v pgdata:/var/lib/postgresql/data --restart unless-stopped pgvector/pgvector:pg17
273-
public static readonly bool EmbeddingIsEnabled = false;
274+
//#elif (database == "SqlServer")
275+
// This requires SQL Server 2025+
276+
//#endif
277+
public static readonly bool IsEmbeddingEnabled = false;
274278
//#endif
275279
}

src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Data/Configurations/Product/ProductConfiguration.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ public void Configure(EntityTypeBuilder<Product> builder)
1616
//#if (database == "PostgreSQL" || database == "SqlServer")
1717
builder.Property(p => p.ShortId).UseSequence("ProductShortId");
1818
//#endif
19-
//#if (database == "PostgreSQL")
20-
if (AppDbContext.EmbeddingIsEnabled)
19+
//#if (database == "PostgreSQL" || database == "SqlServer")
20+
if (AppDbContext.IsEmbeddingEnabled)
2121
{
2222
builder.Property(p => p.Embedding).HasColumnType("vector(1536)"); // 1536 for text-embedding-3-small
2323
}

src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Models/Products/Product.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,13 @@ public partial class Product
4141

4242
//#if (database == "PostgreSQL")
4343
public Pgvector.Vector? Embedding { get; set; }
44+
//#elif (database == "SqlServer")
45+
//#if (IsInsideProjectTemplate == true)
46+
/*
47+
//#endif
48+
public float[]? Embedding { get; set; }
49+
//#if (IsInsideProjectTemplate == true)
50+
*/
51+
//#endif
4452
//#endif
4553
}

src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Program.Services.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
using System.Net;
33
using System.Net.Mail;
44
using System.IO.Compression;
5-
//#if (signalR == true || database == "PostgreSQL")
5+
//#if (signalR == true || database == "PostgreSQL" || database == "SqlServer")
66
using System.ClientModel.Primitives;
77
//#endif
88
//#if (database == "Sqlite")
@@ -54,7 +54,7 @@ public static void AddServerApiProjectServices(this WebApplicationBuilder builde
5454
services.AddScoped<PhoneService>();
5555
services.AddScoped<PhoneServiceJobsRunner>();
5656
//#if (module == "Sales" || module == "Admin")
57-
//#if (signalR == true || database == "PostgreSQL")
57+
//#if (signalR == true || database == "PostgreSQL" || database == "SqlServer")
5858
services.AddScoped<ProductEmbeddingService>();
5959
//#endif
6060
//#endif
@@ -238,7 +238,10 @@ void AddDbContext(DbContextOptionsBuilder options)
238238
//#if (database == "SqlServer")
239239
options.UseSqlServer(configuration.GetConnectionString("SqlServerConnectionString"), dbOptions =>
240240
{
241-
241+
if (AppDbContext.IsEmbeddingEnabled)
242+
{
243+
dbOptions.UseVectorSearch();
244+
}
242245
});
243246
//#elif (database == "PostgreSQL")
244247
options.UseNpgsql(configuration.GetConnectionString("PostgreSQLConnectionString"), dbOptions =>
@@ -372,7 +375,7 @@ void AddDbContext(DbContextOptionsBuilder options)
372375
return options;
373376
});
374377

375-
//#if (signalR == true || database == "PostgreSQL")
378+
//#if (signalR == true || database == "PostgreSQL" || database == "SqlServer")
376379
services.AddHttpClient("AI", c =>
377380
{
378381
c.DefaultRequestVersion = HttpVersion.Version20;

src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/ServerApiSettings.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public partial class ServerApiSettings : SharedSettings
1616
[Required]
1717
public EmailOptions Email { get; set; } = default!;
1818

19-
//#if (signalR == true || database == "PostgreSQL")
19+
//#if (signalR == true || database == "PostgreSQL" || database == "SqlServer")
2020
public AIOptions? AI { get; set; }
2121
//#endif
2222

@@ -190,7 +190,7 @@ public partial class AppIdentityOptions : IdentityOptions
190190
public int MaxPrivilegedSessionsCount { get; set; }
191191
}
192192

193-
//#if (signalR == true || database == "PostgreSQL")
193+
//#if (signalR == true || database == "PostgreSQL" || database == "SqlServer")
194194
public partial class AIOptions
195195
{
196196
public OpenAIOptions? OpenAI { get; set; }

0 commit comments

Comments
 (0)