7

I'm using Entity Framework Core 2 in my application. I have a lot of nullable string columns in my database.

The problem is that I want to save empty strings as NULL in the database.

In old versions of EF, I used a IDbCommandInterceptor for implementing an interceptor, but in EF Core 2, I don't know how to write one ?

3
  • there is an open issue in ef core github page . but does not provide any solution. github.com/aspnet/EntityFrameworkCore/issues/1629 Commented Jul 18, 2018 at 11:48
  • 4
    You could try utilizing Value Conversions introduced in EF Core 2.1, for instance associating value converter like this new ValueConverter<string, string>(v => v == "" ? null : v, v => v) with all these properties (columns). Commented Jul 18, 2018 at 16:13
  • I have the exact opposite of this ... I'm giving it an empty string and it's complaining with a Microsoft.EntityFrameworkCore.DbUpdateException that the field cannot be null. Commented Jul 11, 2019 at 14:24

2 Answers 2

3

There is a new IDbCommandInterceptor interface that should be able to handle this, but it looks complicated.

A simple approach is be to write a function to remove empty strings, and then call it before data is saved within your DbContext class.

public void RemoveEmptyStrings()
{
    // Look for changes
    this.ChangeTracker.DetectChanges();

    // Loop through each entity
    foreach (var entity in this.ChangeTracker.Entries())
    {
        // Use reflection to find editable string properties
        var properties = from p in entity.Entity.GetType().GetProperties()
            where p.PropertyType == typeof(string)
                  && p.CanRead
                  && p.CanWrite
            select p;

        // Loop through each property and replace empty strings with null
        foreach (var property in properties)
        {
            if (string.IsNullOrWhiteSpace(property.GetValue(entity.Entity, null) as string))
                property.SetValue(entity.Entity, null, null);
       }
    }
}

Remember to override each version of SaveChanges(), SaveChanges(bool), SaveChangesAsync() in your DbContext class.

public override int SaveChanges()
{
    // Replace empty strings with null
    this.RemoveEmptyStrings();

    // Continue with base functionality
    return base.SaveChanges();
}
Sign up to request clarification or add additional context in comments.

1 Comment

SaveChanges() seems to call SaveChanges(bool) and SaveChangesAsync(CancellationToken) seems to call SaveChangesAsync(bool, CancellationToken) under the hood so overriding the versions with only the bool seems to be sufficient
1

Be careful with storing a different value in your DB than is in your domain object. Any code that touches this object will behave differently after it's hydrated from the DB.

If you always use String.IsNullOrEmpty(val), you will be ok, but there's guarantee that all code tests strings this way.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.