将非必需的字符串属性从null水合为空字符串

时间:2015-12-07 17:45:49

标签: entity-framework-core

如果我有模型类

public class Foo
{
    public string Property1 { get; set; } = string.Empty;
    ... other properties omitted for brevity
}

它将保存到数据库为null,因为它不是必需属性。但现在当我检索属性为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; }
} 

认为EF必须使用setter但这仍然导致null属性。到目前为止,通过制作这样的属性,我能够解决它的唯一方法是:

private string property1 = string.empty;
public string Property1
{
    get { return property1 ?? string.empty; }
    set { property1 = value ?? string.Empty; }
} 

我真的不必像我那样制作所有属性。

如果我做错事或不正常或者认为错了,任何人都可以提出更清洁的方法来纠正我。我错过了一些更简单的方法来实现这个目标吗?

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

1 个答案:

答案 0 :(得分:2)

问题的原始Entity Framework版本是EF7,这是第一个ef-core版本,后来被重命名为EF-core 1。所描述的行为与当前的EF核心版本(2.1.1)明显不同。

让我提到两个关键点:

1

  

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

这不是当前发生的情况。

参加一个简单的课程:

public class Item
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Code { get; set; } = string.Empty;
}

添加仅设置了Item的{​​{1}}时,将执行以下SQL:

Name

空字符串是插入语句的一部分。另外,从数据库中检索项目时,其exec sp_executesql N'SET NOCOUNT ON; INSERT INTO [Items] ([Code], [Name]) VALUES (@p0, @p1); SELECT [ID] FROM [Items] WHERE @@ROWCOUNT = 1 AND [ID] = scope_identity(); ',N'@p0 nvarchar(4000),@p1 nvarchar(50)',@p0=N'',@p1=N'Item1' 是一个空字符串。

2

  

在此属性的OnModelCreating中,我有:

Code
     

,但它仍存储为null并重新水化为null。

现在也有所不同。参加相同的课程,但现在有:

.HasMaxLength(50)
.HasDefaultValue(string.Empty)

...以及 public string Code { get; set; } // removed "= string.Empty;" 的映射:

Code

...然后这是结果表:

modelBuilder.Entity<Item>().Property(p => p.Code).HasMaxLength(50).HasDefaultValue(string.Empty);

如您所见,映射指令被转换为数据库默认值。

添加仅设置了CREATE TABLE [Items] ( [ID] int NOT NULL IDENTITY, [Name] nvarchar(50) NOT NULL, [Code] nvarchar(50) NULL DEFAULT N'', -- Default constraint CONSTRAINT [PK_Items] PRIMARY KEY ([ID]) ); 的{​​{1}}时,将执行以下SQL:

Item

因此,EF插入项目并回读生成的默认值,以使被跟踪的实体与数据库保持同步。同样,稍后从数据库读取的项目在Name中有一个空字符串。

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