【问题标题】:How do I get EF to persist empty strings as NULL?如何让 EF 将空字符串保留为 NULL?
【发布时间】:2012-02-08 11:35:15
【问题描述】:

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

【问题讨论】:

标签: entity-framework entity-framework-4.1


【解决方案1】:

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

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

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

【讨论】:

  • 请看my function,我很想听听像您这样的专家的一两个提示。
【解决方案2】:

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

我仍然没有优化它,因此非常感谢任何性能提示。

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 中的 TextBoxes 将所有字符串属性设置为空字符串。

我试过设置:

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

但这并没有太大帮助。

【讨论】:

    【解决方案3】:

    这不是实体框架的工作。

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

    或者一开始就做(例如当数据进来时,UI,外部源等)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-09
      • 1970-01-01
      • 1970-01-01
      • 2012-12-19
      • 2015-06-22
      • 2020-07-06
      • 1970-01-01
      相关资源
      最近更新 更多