Entity framework core 将非必需的字符串属性从null变为空字符串

Entity framework core 将非必需的字符串属性从null变为空字符串,entity-framework-core,Entity Framework Core,如果我有一个模型课 public class Foo { public string Property1 { get; set; } = string.Empty; ... other properties omitted for brevity } 由于它不是必需的属性,因此它将以null形式保存到数据库。但现在当我检索实体时,属性为null。 我在这个实体上有很多非必需的字符串属性,我不想对这些属性做很多空检查,我只希望它们在数据库中为空时被重新水化为空字符串。我不介意它们

如果我有一个模型课

public class Foo
{
    public string Property1 { get; set; } = string.Empty;
    ... other properties omitted for brevity
}
由于它不是必需的属性,因此它将以null形式保存到数据库。但现在当我检索实体时,属性为null。 我在这个实体上有很多非必需的字符串属性,我不想对这些属性做很多空检查,我只希望它们在数据库中为空时被重新水化为空字符串。我不介意它们以null形式存储在db中,但是当从db中检索实体时,如果它在db中为null,我希望将其映射回空字符串

我认为这一定是一个相当常见的场景,我想知道我是否缺少一些简单的配置设置或其他方法。我对使用EF相当陌生

在我为该属性创建的OnModelCreating中,我有:

.HasMaxLength(50)
.HasDefaultValue(string.Empty)
但它仍然被存储为null,并被重新水化为null。同样,我不介意它被存储为null,但是如果它在db中为null,我希望它被存储为空字符串

我尝试过这样修改模型类:

private string property1 = string.empty;
public string Property1
{
    get { return property1; }
    set { property1 = value ?? string.Empty; }
} 
private string property1 = string.empty;
public string Property1
{
    get { return property1 ?? string.empty; }
    set { property1 = value ?? string.Empty; }
} 
认为EF必须使用setter,但这仍然导致了null属性。到目前为止,我唯一能够解决这个问题的方法是将该属性设置为:

private string property1 = string.empty;
public string Property1
{
    get { return property1; }
    set { property1 = value ?? string.Empty; }
} 
private string property1 = string.empty;
public string Property1
{
    get { return property1 ?? string.empty; }
    set { property1 = value ?? string.Empty; }
} 
我真的不想把我所有的财产都变成那样

如果我做了错事或不寻常的事,或是想错了,谁能建议一个更干净的方法来做这件事或是纠正我。我是否错过了一些更容易实现这一目标的方法


我不想让属性成为必需的,因为空字符串也不能满足这种情况。

问题的原始实体框架版本是EF7,这是后来重命名为ef core 1的第一个ef core版本。所描述的行为与当前EF核心版本(2.1.1)有很大不同

让我提及两个关键点:

1. 由于它不是必需的属性,因此它将以null形式保存到数据库。但现在当我检索实体时,属性为null

这不是目前发生的事情

以简单的课程为例:

公共类项目
{
公共int ID{get;set;}
公共字符串名称{get;set;}
公共字符串代码{get;set;}=string.Empty;
}
添加仅设置了
名称的
时,执行以下SQL:

exec sp_executesql N'SET NOCOUNT ON;
插入到[项目]([代码],[名称])
数值(@p0,@p1);
选择[ID]
来自[项目]
其中@@ROWCOUNT=1和[ID]=scope_identity();
“,N'@p0 nvarchar(4000),@p1 nvarchar(50)”,@p0=N',@p1=N'Item1”
空字符串是insert语句的一部分。此外,从数据库检索项目时,其
code
为空字符串

2. 在我为该属性创建的OnModelCreating中,我有:

.HasMaxLength(50)
.HasDefaultValue(string.Empty)
.HasMaxLength(50)
.HasDefaultValue(string.Empty)
但它仍然被存储为null,并被重新水化为null

现在情况也不同了。参加同样的课程,但现在有:

公共字符串代码{get;set;}//removed“=string.Empty;”
…和
code
的映射:

modelBuilder.Entity().Property(p=>p.code).HasMaxLength(50).HasDefaultValue(string.Empty);
…然后这是结果表:

创建表[项目](
[ID]int不是空标识,
[名称]nvarchar(50)不为空,
[Code]nvarchar(50)空默认值N'',--默认约束
约束[PK\U项]主键([ID])
);
如您所见,映射指令被转换为数据库默认值

添加仅设置了
名称的
时,执行以下SQL:

exec sp_executesql N'SET NOCOUNT ON;
插入到[项目]([名称])
数值(@p0);
选择[ID],[Code]
来自[项目]
其中@@ROWCOUNT=1和[ID]=scope_identity();
“,N'@p0 nvarchar(50)”,@p0=N'Item1”
因此,EF插入该项并读回生成的默认值,以保持跟踪的实体与数据库同步。类似地,稍后从数据库读取的项在
code
中有一个空字符串

这些发现证实了EF7是EF-core的一个非常不成熟的版本(尽管我没有证实它确实显示了所描述的行为)。自那以后,发生了更多、更深刻的突破性变化。我希望我们很快就会忘记这些早期的EF核心版本。从2.0版开始,EF core最终发展成为一个可用于生产的ORM