Josh Kodroff
Josh Kodroff

Reputation: 28121

How do I get EF to persist empty strings as NULL?

In my domain, there's no important distinction between NULL and an empty string. How do I get EF to ignore the difference between the two and always persist an empty string as NULL?

Upvotes: 4

Views: 6949

Answers (3)

Shimmy Weitzhandler
Shimmy Weitzhandler

Reputation: 104721

Here is a function I placed in my DbContext subclass that replaces empty or whitespace strings with null.

I still didn't optimize it so any performance hints will be very appreciated.

private const string StringType = "String";
private const EntityState SavingState = EntityState.Added | EntityState.Modified;
public override int SaveChanges()
{
  var objectContext = ((IObjectContextAdapter)this).ObjectContext;
  var savingEntries = 
    objectContext.ObjectStateManager.GetObjectStateEntries(SavingState);

  foreach (var entry in savingEntries)
  { 
    var curValues = entry.CurrentValues;        
    var fieldMetadata = curValues.DataRecordInfo.FieldMetadata;
    var stringFields = fieldMetadata.Where(f =>
                         f.FieldType.TypeUsage.EdmType.Name == StringType);
    foreach (var stringField in stringFields)
    {
      var ordinal = stringField.Ordinal;
      var curValue = curValues[ordinal] as string;
      if (curValue != null && curValue.All(char.IsWhiteSpace))
        curValues.SetValue(ordinal, null);
    }
  }
  return base.SaveChanges();
}

Optimization considerations:

  • Identify a string type property by different way other than string comparison I tried to look-up some enumeration of the built-in types but didn't find
  • Cache string fields for types (maybe is unnecessary, will have to decompile and see what the original impl does
  • Order result by entity type, backup iterated entity type, if next iterated entity is same type, use previous metadata, again, if the metadata is anyway there, performance is cheaper the way it is
  • Limit string length for whitespace check - i.e. if a string length > x, skip checking whether its a whitespace string or not

I'm using Silverlight and the TextBoxes in the UI set all the string properties to empty strings.

I tried setting:

<TextBox 
  Text="{Binding MyStringProperty, 
           Mode=TwoWay, 
           ValidatesOnDataErrors=True, 
           TargetNullValue=''}"/>

But it didn't help much.

Upvotes: 5

RPM1984
RPM1984

Reputation: 73112

That's not Entity Framework's job.

You should do it in your repository, or in the database with triggers.

Or do it at the start (e.g when the data comes in, UI, external source, etc)

Upvotes: 1

Ladislav Mrnka
Ladislav Mrnka

Reputation: 364269

Empty string is not default value for string property so it means your code is setting empty strings somewhere. In such case it is your responsibility to handle it.

If you are using code first with POCOs you can use custom setter:

private string _myProperty;
public string MyProperty
{
    get { return _myProperty; }
    set
    {
        if (value == String.Empty)
        {
            _myProperty = null;
        }
        else
        {
            _myProperty = value;
        }
    }
}

Upvotes: 7

Related Questions