7

Question: Is there a way in Entity Framework Core 3.0 to apply value conversion on backing fields?

Context: Let's say I have a Blog entity that contains a list of string values representing post ids. I want to avoid the need to have a join entity/table (as described here) so I do a conversion to store the list as a string in the DB. I also want to protect my model from being modified directly through the PostIds property, so I want to use a backing field for that (as described here).

Something like this:

public class Blog
{
    public int BlogId { get; set; }

    private readonly List<string> _postIds;
    public IReadOnlyCollection<string> PostIds => _postIds;

    public Blog()
    {
        _posts = new List<Post>();
    }
}

And configuration of the context would look something like that:

protected override void OnModelCreating(ModelBuilder modelBuilder)  
{
    // Configuring the backing field
    modelBuilder.Entity<Blog>()
                .Metadata
                .FindNavigation(nameof(Blog.PostIds))
                .SetPropertyAccessMode(PropertyAccessMode.Field);

    // Trying to configure the value conversion, but that doesn't work...
    modelBuilder.Entity<Blog>()
                .Property(e => e.PostIds)
                .HasConversion(v => string.Join(',', v),
                               v => v.Split(','));
}

Any ideas how this configuration could be achieved with the current version of Entity Framework (3.0)?

Absolom
  • 1,369
  • 1
  • 13
  • 28
  • 1
    You can simply make the backing field `string` and the navigation property computed from the backing field. – Alsein Apr 12 '19 at 01:57
  • And if you want to modify the list within the entity class, you can make: (1) a `string` type backing field, (2) a private `IList` property which is implemented by yourself to read from and write to the backing field ,which must have a different name and should be set ignored by EF Core (3) a public navigation property with the same (but CamelCase) name to be configured as `PropertyAccessMode.Field` which converts (2) to a `IReadOnlyCollection` for external read access. – Alsein Apr 12 '19 at 02:10
  • Alternatively, you can use Owned Entity Types to have it stored in a different data table but mapped as an Entity or Value Object to be accessed only via the `Blog` aggregate root. – Alsein Apr 12 '19 at 02:15
  • 1
    Did you ever find out a real solution? I believe the comments above only post workarounds that do not make use of value conversion from ef core – S. ten Brinke Jun 29 '21 at 12:57
  • 1
    @S.tenBrinke ten Brinke I don't remember if we found a way to fix it. Have you tried this: https://stackoverflow.com/a/50375161/638167 – Absolom Jul 06 '21 at 15:16

0 Answers0