Entity Framework Core 2 - 将空字符串保存为 null 在数据库中

7
我在我的应用程序中使用Entity Framework Core 2。我在数据库中有很多可为空的字符串列。
问题是我想把空字符串保存为NULL到数据库中。
在EF的旧版本中,我使用了IDbCommandInterceptor来实现拦截器,但在EF Core 2中,我不知道该如何编写一个?

EF Core的GitHub页面上有一个未解决的问题,但是没有提供任何解决方案。 https://github.com/aspnet/EntityFrameworkCore/issues/1629 - jsDevia
4
你可以尝试使用EF Core 2.1中引入的值转换(Value Conversions)功能,例如将这样一个关联值转换器 new ValueConverter<string, string>(v => v == "" ? null : v, v => v) 应用于所有这些属性(列)。该功能能够为你提供更好的灵活性。 - Ivan Stoev
我遇到了完全相反的问题... 我给它一个空字符串,但它却报错 Microsoft.EntityFrameworkCore.DbUpdateException,说该字段不能为空。 - War
2个回答

3

现在有一个新的IDbCommandInterceptor接口,它应该能够处理这个问题,但看起来比较复杂。

一种简单的方法是编写一个函数来移除空字符串,在数据保存到你的DbContext类之前调用它。

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

记得在你的DbContext类中,覆盖每个SaveChanges()SaveChanges(bool)SaveChangesAsync()版本。

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

    // Continue with base functionality
    return base.SaveChanges();
}

似乎SaveChanges()会调用SaveChanges(bool),而SaveChangesAsync(CancellationToken)会在幕后调用SaveChangesAsync(bool, CancellationToken),因此仅覆盖带有bool参数的版本似乎就足够了。 - Memet Olsen

1

在数据库中存储与域对象不同的值时要小心。任何触及此对象的代码在从数据库中提取后都会表现出不同的行为。

如果您始终使用String.IsNullOrEmpty(val),那么就没问题了,但不能保证所有代码都以这种方式测试字符串。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接