如何让EF将空字符串保持为NULL?

时间:2011-06-14 00:37:04

标签: entity-framework entity-framework-4.1

在我的域中,NULL和空字符串之间没有重要的区别。如何让EF忽略两者之间的差异并始终将空字符串保持为NULL?

3 个答案:

答案 0 :(得分:5)

空字符串不是字符串属性的默认值,因此这意味着您的代码在某处设置空字符串。在这种情况下,您有责任处理它。

如果您首先使用POCO代码,则可以使用自定义设置器:

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

答案 1 :(得分:3)

这是我放在DbContext子类中的一个函数,用空格替换空或空白字符串。

我仍然没有优化它,所以任何性能提示都将非常受欢迎。

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();
}

优化注意事项:

  • 通过不同于字符串比较的方式识别string类型属性我试图查找内置类型的一些枚举但未找到
  • 类型的缓存字符串字段(可能是不必要的,必须反编译并查看原始impl的作用
  • 按实体类型排序结果,备份迭代实体类型,如果下一个迭代实体是同一类型,请再次使用以前的元数据,如果元数据在那里,那么性能会更便宜
  • 限制字符空间检查的字符串长度 - 即字符串长度> x,跳过检查是否是空白字符串

我正在使用Silverlight,并且UI中的TextBox es将所有字符串属性设置为空字符串。

我尝试过设置:

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

但它没有多大帮助。

答案 2 :(得分:0)

这不是实体框架的工作。

您应该在您的存储库或带有触发器的数据库中执行此操作。

或者在开始时进行(例如,当数据进入时,UI,外部源等)