Skip to content

Support IReadOnlyList for Complex CollectionsΒ #37405

@tpoiesz

Description

@tpoiesz

What problem are you trying to solve?

It can be useful to expose collection navigation properties as IReadOnlyList to prevent client code from adding to the list directly. Instead a method is available that can do some validation and then add to the list (private property) directly. For example:

using Microsoft.EntityFrameworkCore;

const string connectionString = "Server=localhost;Database=complex-issues;Port=5432;User Id=postgres;Password=postgres;Include Error Detail=true";
var options = new DbContextOptionsBuilder<AppDbContext>()
  .UseNpgsql(connectionString)
  .Options;
var dbContext = new AppDbContext(options);
await dbContext.Database.EnsureDeletedAsync();
await dbContext.Database.EnsureCreatedAsync();

public class Entity
{
  public Guid Id { get; init; }
  private List<ComplexEntity> _complexEntities = [];
  public IReadOnlyList<ComplexEntity> ComplexEntities => _complexEntities.AsReadOnly();

  public void AddComplexEntity(ComplexEntity complexEntity)
  {
    //Some validation
    _complexEntities.Add(complexEntity);
  }
}

public class ComplexEntity
{
  public required string Value { get; init; }
}

public class AppDbContext(DbContextOptions options) : DbContext(options)
{
  public DbSet<Entity> Entities { get; init; }

  protected override void OnModelCreating(ModelBuilder modelBuilder)
  {
    base.OnModelCreating(modelBuilder);
    modelBuilder.Entity<Entity>().ComplexCollection(entity => entity.ComplexEntities).ToJson();
  }
}

This scenario is supported when using OwnsMany(...).ToJson(), but when converting to ComplexCollection we receive the following exception:

System.InvalidOperationException: The complex collection 'Entity'.'ComplexEntities' is of type 'IReadOnlyList<ComplexEntity>' which does not implement 'IList<ComplexEntity>'.

Describe the solution you'd like

For this scenario to work, so it's easier to convert from Owned entities to Complex entities

Metadata

Metadata

Assignees

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions