我在我的应用程序中使用Entity Framework Core 2。我在数据库中有很多可为空的字符串列。
问题是我想把空字符串保存为
在EF的旧版本中,我使用了
问题是我想把空字符串保存为
NULL
到数据库中。在EF的旧版本中,我使用了
IDbCommandInterceptor
来实现拦截器,但在EF Core 2中,我不知道该如何编写一个?NULL
到数据库中。IDbCommandInterceptor
来实现拦截器,但在EF Core 2中,我不知道该如何编写一个?现在有一个新的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在数据库中存储与域对象不同的值时要小心。任何触及此对象的代码在从数据库中提取后都会表现出不同的行为。
如果您始终使用String.IsNullOrEmpty(val),那么就没问题了,但不能保证所有代码都以这种方式测试字符串。
new ValueConverter<string, string>(v => v == "" ? null : v, v => v)
应用于所有这些属性(列)。该功能能够为你提供更好的灵活性。 - Ivan Stoev