Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework Core - Has Conversion - Support Null Values

I have an EF model with a notification emails property. The notification emails are saved in the database as string separated by ';'. I added a conversion to retrieve the data as a ICollection in the model. This is working well except one thing: when the string is null the collection is also null, and I want to convert it to an empty collection instead. is it possible?

//This is my code
  entity.Property(e => e.NotificationEmails)
             .HasConversion(
                v => string.Join(",", v.Select(s => s.Trim())),
                v => v.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries));

I tried to add String.IsNullOrEmpty(v) but EF ignores it.

like image 425
Tal Humy Avatar asked Oct 15 '22 15:10

Tal Humy


1 Answers

Currently, it isn't possible :

https://learn.microsoft.com/en-us/ef/core/modeling/value-conversions#configuring-a-value-converter

A null value will never be passed to a value converter. This makes the implementation of conversions easier and allows them to be shared amongst nullable and non-nullable properties.

It isn't elegant, but you can use a backing field :

public class Notification
{
    private List<string> _emails = new List<string>();
    public List<string> Emails 
    {
        get => _emails;
        set => _emails = value ?? new List<string>();
    }
}

public class NotificationContext : DbContext
{
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<Notification>().Property(d => d.Emails).HasConversion(
                v => string.Join(",", v.Select(s => s.Trim())),
                v => v.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList()
            );
            modelBuilder.Entity<Notification>()
                .Property(b => b.Emails)
                .HasField("_emails")
                .UsePropertyAccessMode(PropertyAccessMode.Property);
    }
}

Note : in where, a empty list will not be translated by null, but by a empty string.

Edit : This feature is available from EF Core 6, but bugged. See this comment :

For anyone watching this issue: there are significant problems when executing queries that either convert nulls in the database to non-nulls in code or vice-versa. Therefore, we have marked this feature as internal for EF Core 6.0. You can still use it, but you will get a compiler warning. The warning can be disabled with a #pragma.

like image 134
vernou Avatar answered Oct 27 '22 11:10

vernou