SQLite 错误 19:'NOT NULL constraint failed' - C# 8 中的字符串是否默认可为空?
SQLite Error 19: 'NOT NULL constraint failed' - Are strings nullable by default in C# 8?
我在将我的项目从 .NET 5 迁移到 .NET 6 后遇到了这个问题。我正在使用最新版本的 SQLite 作为数据库。
似乎假设字符串默认不再可为空而不是可为空。每当 Entity Framework 尝试写入不是主键或外键的字段时,我都会收到错误 SQLite Error 19: 'NOT NULL constraint failed
。在 .NET 5 中,我没有收到此错误。
我还注意到 VS 2022 Intellisense 在导致此错误的每个 属性 名称下方都有一条绿色指示线。它表示 Non-nullable property must contain a non null-value when exiting constructor. Consider declaring the property as nullable.
当我将可空运算符 ?
添加到导致错误的 属性 类型时,绿色指示线和 SQLite Error 19: 'NOT NULL constraint failed'
消失。
导致错误的代码示例:
[Table("ApplicationUser")]
public class ApplicaitonUser : IdentityUser
{
// Inherited properties https://docs.microsoft.com/en-us/aspnet/core/security/authentication/customize-identity-model?view=aspnetcore-6.0
[Key]
public new int Id { get; set; } // every other property causes the SQLite 19 error
[PersonalData]
public string FirstName { get; set; }
[PersonalData]
public string MiddleName { get; set; }
[PersonalData]
public string LastName { get; set; }
[PersonalData]
public string PreferredName { get; set; }
// Address Table Foreign Key relationship navigation property
[PersonalData]
ICollection<UsAddress> UsAddresses { get; set; }
}
Microsoft 在 C# 8 中引入了“可空感知上下文”。
在可空感知上下文中:
- 引用类型T的变量必须用non-null初始化,
并且可能永远不会被分配一个可能为空的值。
- 引用类型T的变量?可以用 null 或初始化
分配为空,但需要在之前检查是否为空
de-referencing.
- T类型的变量m?申请时被认为是 non-null
null-forgiving 运算符,如 m!.
non-null可引用类型 T 和可空引用类型 T 之间的区别?由编译器对前面规则的解释强制执行。一个T类型的变量和一个T类型的变量?由相同的 .NET 类型表示。
示例:
string notNull = "Hello";
string? nullable = default;
notNull = nullable!; // null forgiveness
可以使用项目文件中的 <nullable>enable</nullable
或禁用属性打开和关闭此功能。由于默认情况下禁用该功能,因此也可以删除该属性以禁用它。
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
附加信息:
Learn techniques to resolve nullable warnings
Update a codebase with nullable reference types to improve null diagnostic warnings
我在将我的项目从 .NET 5 迁移到 .NET 6 后遇到了这个问题。我正在使用最新版本的 SQLite 作为数据库。
似乎假设字符串默认不再可为空而不是可为空。每当 Entity Framework 尝试写入不是主键或外键的字段时,我都会收到错误 SQLite Error 19: 'NOT NULL constraint failed
。在 .NET 5 中,我没有收到此错误。
我还注意到 VS 2022 Intellisense 在导致此错误的每个 属性 名称下方都有一条绿色指示线。它表示 Non-nullable property must contain a non null-value when exiting constructor. Consider declaring the property as nullable.
当我将可空运算符 ?
添加到导致错误的 属性 类型时,绿色指示线和 SQLite Error 19: 'NOT NULL constraint failed'
消失。
导致错误的代码示例:
[Table("ApplicationUser")]
public class ApplicaitonUser : IdentityUser
{
// Inherited properties https://docs.microsoft.com/en-us/aspnet/core/security/authentication/customize-identity-model?view=aspnetcore-6.0
[Key]
public new int Id { get; set; } // every other property causes the SQLite 19 error
[PersonalData]
public string FirstName { get; set; }
[PersonalData]
public string MiddleName { get; set; }
[PersonalData]
public string LastName { get; set; }
[PersonalData]
public string PreferredName { get; set; }
// Address Table Foreign Key relationship navigation property
[PersonalData]
ICollection<UsAddress> UsAddresses { get; set; }
}
Microsoft 在 C# 8 中引入了“可空感知上下文”。
在可空感知上下文中:
- 引用类型T的变量必须用non-null初始化, 并且可能永远不会被分配一个可能为空的值。
- 引用类型T的变量?可以用 null 或初始化 分配为空,但需要在之前检查是否为空 de-referencing.
- T类型的变量m?申请时被认为是 non-null null-forgiving 运算符,如 m!.
non-null可引用类型 T 和可空引用类型 T 之间的区别?由编译器对前面规则的解释强制执行。一个T类型的变量和一个T类型的变量?由相同的 .NET 类型表示。
示例:
string notNull = "Hello";
string? nullable = default;
notNull = nullable!; // null forgiveness
可以使用项目文件中的 <nullable>enable</nullable
或禁用属性打开和关闭此功能。由于默认情况下禁用该功能,因此也可以删除该属性以禁用它。
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
附加信息:
Learn techniques to resolve nullable warnings
Update a codebase with nullable reference types to improve null diagnostic warnings