diff --git a/dotnet/src/VectorData/PgVector/PostgresSqlBuilder.cs b/dotnet/src/VectorData/PgVector/PostgresSqlBuilder.cs index acfa930a67ec..322820f6d9af 100644 --- a/dotnet/src/VectorData/PgVector/PostgresSqlBuilder.cs +++ b/dotnet/src/VectorData/PgVector/PostgresSqlBuilder.cs @@ -269,7 +269,7 @@ internal static void BuildGetCommand(NpgsqlCommand command, string schema, internal static void BuildGetBatchCommand(NpgsqlCommand command, string schema, string tableName, CollectionModel model, List keys, bool includeVectors = false) where TKey : notnull { - NpgsqlDbType? keyType = PostgresPropertyMapping.GetNpgsqlDbType(typeof(TKey)) ?? throw new ArgumentException($"Unsupported key type {typeof(TKey).Name}"); + NpgsqlDbType? keyType = PostgresPropertyMapping.GetNpgsqlDbType(model.KeyProperty.Type) ?? throw new UnreachableException($"Unsupported key type {model.KeyProperty.Type.Name}"); // Generate the column names var columns = model.Properties diff --git a/dotnet/test/VectorData/InMemory.ConformanceTests/ModelTests/InMemoryDynamicModelTests.cs b/dotnet/test/VectorData/InMemory.ConformanceTests/ModelTests/InMemoryDynamicModelTests.cs index 7f2c7d073e22..5333f1880cac 100644 --- a/dotnet/test/VectorData/InMemory.ConformanceTests/ModelTests/InMemoryDynamicModelTests.cs +++ b/dotnet/test/VectorData/InMemory.ConformanceTests/ModelTests/InMemoryDynamicModelTests.cs @@ -27,6 +27,30 @@ public override async Task GetAsync_single_record(bool includeVectors) AssertEquivalent(expectedRecord, received, includeVectors: true, fixture.TestStore.VectorsComparable); } + public override async Task GetAsync_multiple_records(bool includeVectors) + { + if (includeVectors) + { + await base.GetAsync_multiple_records(includeVectors); + return; + } + + // InMemory always returns the vectors (IncludeVectors = false isn't respected) + var expectedRecords = fixture.TestData.Take(2); + var ids = expectedRecords.Select(record => record[KeyPropertyName]!); + + var received = await fixture.Collection.GetAsync(ids, new() { IncludeVectors = false }).ToArrayAsync(); + + foreach (var record in expectedRecords) + { + AssertEquivalent( + record, + received.Single(r => r[KeyPropertyName]!.Equals(record[KeyPropertyName])), + includeVectors: true, + fixture.TestStore.VectorsComparable); + } + } + public override async Task GetAsync_with_filter(bool includeVectors) { if (includeVectors) diff --git a/dotnet/test/VectorData/VectorData.ConformanceTests/ModelTests/DynamicModelTests.cs b/dotnet/test/VectorData/VectorData.ConformanceTests/ModelTests/DynamicModelTests.cs index e27fac2eefe8..f81b80c9c044 100644 --- a/dotnet/test/VectorData/VectorData.ConformanceTests/ModelTests/DynamicModelTests.cs +++ b/dotnet/test/VectorData/VectorData.ConformanceTests/ModelTests/DynamicModelTests.cs @@ -24,24 +24,23 @@ public virtual async Task GetAsync_single_record(bool includeVectors) AssertEquivalent(expectedRecord, received, includeVectors, fixture.TestStore.VectorsComparable); } - // TODO: https://github.com/microsoft/semantic-kernel/issues/13303 - // [ConditionalTheory, MemberData(nameof(IncludeVectorsData))] - // public virtual Task GetAsync_multiple_records(bool includeVectors) - // { - // var expectedRecords = fixture.TestData.Take(2); - // var ids = expectedRecords.Select(record => record[KeyPropertyName]!); - - // var received = await fixture.Collection.GetAsync(ids, new() { IncludeVectors = includeVectors }).ToArrayAsync(); - - // foreach (var record in expectedRecords) - // { - // AssertEquivalent( - // record, - // received.Single(r => r[KeyPropertyName]!.Equals(record[KeyPropertyName])), - // includeVectors, - // fixture.TestStore.VectorsComparable); - // } - // } + [ConditionalTheory, MemberData(nameof(IncludeVectorsData))] + public virtual async Task GetAsync_multiple_records(bool includeVectors) + { + var expectedRecords = fixture.TestData.Take(2); + var ids = expectedRecords.Select(record => record[KeyPropertyName]!); + + var received = await fixture.Collection.GetAsync(ids, new() { IncludeVectors = includeVectors }).ToArrayAsync(); + + foreach (var record in expectedRecords) + { + AssertEquivalent( + record, + received.Single(r => r[KeyPropertyName]!.Equals(record[KeyPropertyName])), + includeVectors, + fixture.TestStore.VectorsComparable); + } + } [ConditionalFact] public virtual async Task GetAsync_throws_for_null_key() @@ -241,42 +240,39 @@ public virtual async Task Update_single_record() AssertEquivalent(updated, received, includeVectors: true, fixture.TestStore.VectorsComparable); } - // TODO: https://github.com/microsoft/semantic-kernel/issues/13303 - // [ConditionalFact] - // public virtual async Task Insert_multiple_records() - // { - // Dictionary[] newRecords = - // [ - // new() - // { - // [KeyPropertyName] = fixture.GenerateNextKey(), - // [IntegerPropertyName] = 100, - // [StringPropertyName] = "New record 1", - // [EmbeddingPropertyName] = new ReadOnlyMemory([10, 0, 1]) - // }, - // new() - // { - // [KeyPropertyName] = fixture.GenerateNextKey(), - // [IntegerPropertyName] = 101, - // [StringPropertyName] = "New record 2", - // [EmbeddingPropertyName] = new ReadOnlyMemory([10, 0, 2]) - // }, - // ]; - - // var keys = newRecords.Select(record => record[KeyPropertyName]!).ToArray(); - // Assert.Empty(await this.Collection.GetAsync(keys).ToArrayAsync()); - - // await this.Collection.UpsertAsync(newRecords); - - // var received = await this.Collection.GetAsync(keys, new() { IncludeVectors = true }).ToArrayAsync(); - - // Assert.Collection( - // received.OrderBy(r => r[IntegerPropertyName]), - // r => AssertEquivalent(newRecords[0], r, includeVectors: true, fixture.TestStore.VectorsComparable), - // r => AssertEquivalent(newRecords[1], r, includeVectors: true, fixture.TestStore.VectorsComparable)); - - // Assert.Equal(fixture.TestData.Count + 2, await this.GetRecordCount()); - // } + [ConditionalFact] + public virtual async Task Insert_multiple_records() + { + Dictionary[] newRecords = + [ + new() + { + [KeyPropertyName] = fixture.GenerateNextKey(), + [IntegerPropertyName] = 100, + [StringPropertyName] = "New record 1", + [EmbeddingPropertyName] = new ReadOnlyMemory([10, 0, 1]) + }, + new() + { + [KeyPropertyName] = fixture.GenerateNextKey(), + [IntegerPropertyName] = 101, + [StringPropertyName] = "New record 2", + [EmbeddingPropertyName] = new ReadOnlyMemory([10, 0, 2]) + }, + ]; + + var keys = newRecords.Select(record => record[KeyPropertyName]!).ToArray(); + Assert.Empty(await this.Collection.GetAsync(keys).ToArrayAsync()); + + await this.Collection.UpsertAsync(newRecords); + + var received = await this.Collection.GetAsync(keys, new() { IncludeVectors = true }).ToArrayAsync(); + + Assert.Collection( + received.OrderBy(r => r[IntegerPropertyName]), + r => AssertEquivalent(newRecords[0], r, includeVectors: true, fixture.TestStore.VectorsComparable), + r => AssertEquivalent(newRecords[1], r, includeVectors: true, fixture.TestStore.VectorsComparable)); + } #endregion Upsert