Joe*_*tte 6 entity-framework-core
如果我有一个模型类
public class Foo
{
public string Property1 { get; set; } = string.Empty;
... other properties omitted for brevity
}
Run Code Online (Sandbox Code Playgroud)
它被保存到数据库为null,因为它不是必需的属性.但现在当我检索属性为null的实体时.我在这个实体上有很多不需要的字符串属性,我不想对这些属性进行大量的空值检查,我只是希望它们在数据库中为null时被重新水化为空字符串.我不介意它们作为null存储在db中,但是当从db中检索实体时,如果它在db中为null,我希望将它映射回空字符串.
我认为这必须是一个相当常见的场景,并且想知道我是否缺少一些简单的方法来配置设置或其他东西.我是使用EF的新手.
在我的OnModelCreating这个属性我有:
.HasMaxLength(50)
.HasDefaultValue(string.Empty)
Run Code Online (Sandbox Code Playgroud)
但它仍然存储为null并重新水合为null.我再次不介意它被存储为null但是如果它在db中为null,我希望它作为空字符串水合.
我尝试像这样修改模型类:
private string property1 = string.empty;
public string Property1
{
get { return property1; }
set { property1 = value ?? string.Empty; }
}
Run Code Online (Sandbox Code Playgroud)
认为EF必须使用setter但这仍然导致null属性.到目前为止,通过制作这样的属性,我能够解决它的唯一方法是:
private string property1 = string.empty;
public string Property1
{
get { return property1 ?? string.empty; }
set { property1 = value ?? string.Empty; }
}
Run Code Online (Sandbox Code Playgroud)
我真的宁愿不必像我这样做所有的财产.
任何人都可以提出一个更清洁的方法来做这件事或纠正我,如果我做错了什么或不寻常或认为它错了.我错过了一些更容易实现的方法吗?
我不想使属性成为必需属性,因为空字符串也不满足该情况.
该问题的原始实体框架版本是 EF7,第一个 ef-core 版本,后来更名为 EF-core 1。所描述的行为与当前 EF-core 版本 (2.1.1) 有很大不同。
我先提一下两个关键点:
它以 null 的形式保存到数据库中,因为它不是必需的属性。但现在当我检索实体时,属性为空。
目前情况并非如此。
参加一个简单的课程:
public class Item
{
public int ID { get; set; }
public string Name { get; set; }
public string Code { get; set; } = string.Empty;
}
Run Code Online (Sandbox Code Playgroud)
当添加其中Item仅Name设置时,执行以下SQL:
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'
Run Code Online (Sandbox Code Playgroud)
空字符串是插入语句的一部分。此外,当从数据库检索项目时,它Code是一个空字符串。
在我为此属性的 OnModelCreating 中,我有:
Run Code Online (Sandbox Code Playgroud).HasMaxLength(50) .HasDefaultValue(string.Empty)但它仍然被存储为 null 并重新水化为 null。
现在情况也不同了。参加相同的课程,但现在有:
public string Code { get; set; } // removed "= string.Empty;"
Run Code Online (Sandbox Code Playgroud)
...以及映射Code:
modelBuilder.Entity<Item>().Property(p => p.Code).HasMaxLength(50).HasDefaultValue(string.Empty);
Run Code Online (Sandbox Code Playgroud)
...然后这是结果表:
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])
);
Run Code Online (Sandbox Code Playgroud)
如您所见,映射指令被转换为数据库默认值。
当添加其中Item仅Name设置时,执行以下SQL:
exec sp_executesql N'SET NOCOUNT ON;
INSERT INTO [Items] ([Name])
VALUES (@p0);
SELECT [ID], [Code]
FROM [Items]
WHERE @@ROWCOUNT = 1 AND [ID] = scope_identity();
',N'@p0 nvarchar(50)',@p0=N'Item1'
Run Code Online (Sandbox Code Playgroud)
因此 EF 插入项目并读回生成的默认值,以保持跟踪实体与数据库同步。同样,稍后从数据库读取的项目在 中具有空字符串Code。
这些发现证实 EF7 是 EF-core 的一个非常不成熟的版本(尽管我没有确认它确实显示了所描述的行为)。自那以后,发生了更多、更深刻的突破性变化。我希望我们很快就会忘记这些早期的 EF-core 版本。从 2.0 版本开始,EF-core 终于发展成为一个生产就绪的 ORM。
| 归档时间: |
|
| 查看次数: |
400 次 |
| 最近记录: |