fix: migrate to IDbContextFactory and remove direct AppDbContext from DI (#11)
Reviewed-on: #11 Co-authored-by: Marek Jasiński <jasins.marek@gmail.com> Co-committed-by: Marek Jasiński <jasins.marek@gmail.com>
This commit was merged in pull request #11.
This commit is contained in:
@@ -4,7 +4,8 @@ using MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.AI;
|
||||
using NexusReader.Application.DTOs.AI;
|
||||
using NexusReader.Application.Abstractions.Persistence;
|
||||
|
||||
using NexusReader.Data.Persistence;
|
||||
using Pgvector;
|
||||
using Pgvector.EntityFrameworkCore;
|
||||
using System.Text.Json;
|
||||
@@ -16,14 +17,14 @@ public record SearchLibrarySemanticallyQuery(string QueryText, string TenantId,
|
||||
|
||||
public class SearchLibrarySemanticallyQueryHandler : IRequestHandler<SearchLibrarySemanticallyQuery, Result<List<SemanticSearchResultDto>>>
|
||||
{
|
||||
private readonly IApplicationDbContext _dbContext;
|
||||
private readonly IDbContextFactory<AppDbContext> _dbContextFactory;
|
||||
private readonly IEmbeddingGenerator<string, Embedding<float>> _embeddingGenerator;
|
||||
|
||||
|
||||
public SearchLibrarySemanticallyQueryHandler(
|
||||
IApplicationDbContext dbContext,
|
||||
IDbContextFactory<AppDbContext> dbContextFactory,
|
||||
IEmbeddingGenerator<string, Embedding<float>> embeddingGenerator)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_dbContextFactory = dbContextFactory;
|
||||
_embeddingGenerator = embeddingGenerator;
|
||||
}
|
||||
|
||||
@@ -34,6 +35,7 @@ public class SearchLibrarySemanticallyQueryHandler : IRequestHandler<SearchLibra
|
||||
return Result.Fail("Query text cannot be empty.");
|
||||
}
|
||||
|
||||
using var dbContext = _dbContextFactory.CreateDbContext();
|
||||
try
|
||||
{
|
||||
// 1. Generate embedding for user query
|
||||
@@ -41,7 +43,7 @@ public class SearchLibrarySemanticallyQueryHandler : IRequestHandler<SearchLibra
|
||||
var queryVector = new Vector(embeddingResponse.First().Vector.ToArray());
|
||||
|
||||
// 2. Perform Cosine Similarity Search on Knowledge Units
|
||||
var candidates = await _dbContext.KnowledgeUnits
|
||||
var candidates = await dbContext.KnowledgeUnits
|
||||
.AsNoTracking()
|
||||
.Where(x => (x.TenantId == request.TenantId || x.TenantId == "global") && x.Vector != null)
|
||||
.OrderBy(x => x.Vector!.CosineDistance(queryVector))
|
||||
@@ -51,7 +53,7 @@ public class SearchLibrarySemanticallyQueryHandler : IRequestHandler<SearchLibra
|
||||
if (!candidates.Any())
|
||||
{
|
||||
// Fallback to legacy cache if no granular units found
|
||||
var legacyResults = await _dbContext.SemanticKnowledgeCache
|
||||
var legacyResults = await dbContext.SemanticKnowledgeCache
|
||||
.AsNoTracking()
|
||||
.Where(x => x.TenantId == request.TenantId && x.Vector != null)
|
||||
.OrderBy(x => x.Vector!.CosineDistance(queryVector))
|
||||
@@ -68,13 +70,13 @@ public class SearchLibrarySemanticallyQueryHandler : IRequestHandler<SearchLibra
|
||||
|
||||
// 3. Graph Expansion: Pull related units (e.g. Definitions, Next steps)
|
||||
var candidateIds = candidates.Select(c => c.Id).ToList();
|
||||
var links = await _dbContext.KnowledgeUnitLinks
|
||||
var links = await dbContext.KnowledgeUnitLinks
|
||||
.AsNoTracking()
|
||||
.Where(l => candidateIds.Contains(l.SourceUnitId) && (l.RelationType == "Defines" || l.RelationType == "Next"))
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
var relatedIds = links.Select(l => l.TargetUnitId).Distinct().ToList();
|
||||
var relatedUnits = await _dbContext.KnowledgeUnits
|
||||
var relatedUnits = await dbContext.KnowledgeUnits
|
||||
.AsNoTracking()
|
||||
.Where(u => relatedIds.Contains(u.Id))
|
||||
.ToDictionaryAsync(u => u.Id, cancellationToken);
|
||||
|
||||
Reference in New Issue
Block a user