【发布时间】:2021-10-19 07:53:48
【问题描述】:
我正在尝试在我的几个 EF 模型上使用默认值,但我注意到我误解了 HasDefaultValue 行为,或者它没有正常工作。
我有下表和支持模型
CREATE TABLE [dbo].[packages]
(
[Scnumber] BIGINT NOT NULL,
[PU] INT NOT NULL,
[State] SMALLINT NOT NULL DEFAULT 0,
[Status] [smallint] NOT NULL,
[Created] DATETIME NOT NULL DEFAULT GETDATE(),
CONSTRAINT [PK_packages] PRIMARY KEY CLUSTERED ([Scnumber] ASC) ON [PRIMARY],
)
[Table("packages", Schema = "dbo")]
public class Package
{
[Key]
[Column(TypeName = "bigint")]
public long Scnumber { get; set; }
[Column]
[Required]
public int PU { get; set; }
[Column(TypeName = "smallint")]
[Required]
public PackageStatus Status { get; set; }
[Column(TypeName = "tinyint")]
public RecordState State { get; set; }
[Column]
public DateTime? Created { get; set; }
}
为了应用默认值,我的OnModelCreating() 中还包含以下内容
modelBuilder.Entity<Package>(entity =>
{
entity.Property(r => r.State)
.HasDefaultValue(RecordState.Active);
entity.Property(r => r.Created)
.HasDefaultValue(DateTime.Now);
});
当我尝试保存新对象时,出现以下异常:
SqlException:无法将值 NULL 插入“状态”列,表 'app.dbo.packages';列不允许空值。 插入失败。
这很令人困惑,好像我在保存对象之前检查了它,它有一个默认值,但是我得到了这个异常。我知道最简单的解决方案是简单地确保在创建对象时设置 state 的值,但这违背了HasDefaultValue 的目的。
-- 编辑--
当我尝试添加一个新对象时,我会执行以下操作
var package = new Package { Scnumber = 0123456718, PU = 1001 };
_context.Packages.Add(region);
_context.SaveChanges();
这没有什么不正常但失败了,但如果我运行以下它就可以了
var package = new Package {Scnumber = 0123456718, PU = 1001, Status = PackageStatus.Rejected, State = RecordState.Staging, Created = DateTime.Now };
_context.Packages.Add(region);
_context.SaveChanges();
public enum PackageStatus : short
{
New,
PendingValidation,
CheckedOut,
Approved,
Rejected,
PendingRender,
Rendered,
RenderFailed,
PendingPrint,
Printed,
PrintFailed,
Cancelled,
PendingDownload,
Downloaded,
DownloadError,
SystemUpdated,
}
public enum RecordState : byte
{
Active,
Deleted,
Staging,
}
【问题讨论】:
-
我会尝试在 State 上添加 Required 属性。
-
作为一种解决方法,您可以在 Package/Region 类中设置默认值:
public RecordState State { get; set; } = RecordState.Active;。在这种情况下,任何地方的每个对象都将按照相同的规则工作。 -
这是一个我没有考虑过的有效选项,但我觉得这会让我发疯,直到我明白这里发生了什么。
-
你能显示
PackageStatus和RecordState枚举吗?您还显示了Package实体,但示例代码显示了Region。 -
State表列类型smallint和enum类型byte之间存在一些差异,这在我的情况下导致(EF Core 2.0.1)“无效转换异常”。一旦我将枚举类型更改为short或将 db 列类型更改为tinyint,示例代码将执行而不会出错。可能您使用的是较旧的 EF Core 版本?
标签: c# entity-framework entity-framework-core