efcore icon indicating copy to clipboard operation
efcore copied to clipboard

Cosmos: allow value converters for collections of primitive types

Open AndriySvyryd opened this issue 4 years ago • 2 comments

See https://github.com/npgsql/efcore.pg/blob/main/src/EFCore.PG/Storage/ValueConversion/INpgsqlArrayConverter.cs for a way of implementing this.

Also try to use built-in converters automatically, see https://github.com/npgsql/efcore.pg/blob/main/src/EFCore.PG/Storage/ValueConversion/NpgsqlValueConverterSelector.cs

AndriySvyryd avatar Jul 27 '21 21:07 AndriySvyryd

Note from triage: also consider other issues related to primitive collections--see label area-primitive-collections.

ajcvickers avatar Oct 26 '22 10:10 ajcvickers

Note for team: either a duplicate of #4179, or already supported if the issue means using value converters explicitly.

ajcvickers avatar Feb 08 '24 17:02 ajcvickers

Related to #34026

AndriySvyryd avatar Jan 14 '25 21:01 AndriySvyryd

See #36330 for failing Contains over parameterized scalar collection of value-converted elements.

Minimal repro
await using var context = new BlogContext();
await context.Database.EnsureDeletedAsync();
await context.Database.EnsureCreatedAsync();

List<ThingId> list = [new("a"), new("b")];

// this throws an exception:
// System.InvalidOperationException: Couldn't find array type mapping when applying item/array mappings
var results = await context.Things.Where(x => list.Contains(x.Id)).ToListAsync();

Console.WriteLine(results.Count);

public class BlogContext : DbContext
{
    public DbSet<Thing> Things { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        => optionsBuilder
            .UseCosmos(
                Environment.GetEnvironmentVariable("CosmosNoSql__ConnectionString")!,
                databaseName: "test",
                o => o
                    .ConnectionMode(ConnectionMode.Gateway)
                    .HttpClientFactory(() => new HttpClient(
                        new HttpClientHandler
                        {
                            ServerCertificateCustomValidationCallback =
                                HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
                        })))
            .LogTo(Console.WriteLine, LogLevel.Information)
            .EnableSensitiveDataLogging();

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Thing>().Property(x => x.Id).HasConversion(v => v.Value, v => new ThingId(v));
    }
}

public record Thing
{
    public ThingId Id { get; set; }
    public string Name { get; set; }
}

public record ThingId(string Value);

roji avatar Oct 05 '25 16:10 roji