【问题标题】:EntityFramework Core 2 Default ValuesEntityFramework Core 2 默认值
【发布时间】: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;。在这种情况下,任何地方的每个对象都将按照相同的规则工作。
  • 这是一个我没有考虑过的有效选项,但我觉得这会让我发疯,直到我明白这里发生了什么。
  • 你能显示PackageStatusRecordState枚举吗?您还显示了Package 实体,但示例代码显示了Region
  • State 表列类型smallintenum 类型byte 之间存在一些差异,这在我的情况下导致(EF Core 2.0.1)“无效转换异常”。一旦我将枚举类型更改为 short 或将 db 列类型更改为 tinyint,示例代码将执行而不会出错。可能您使用的是较旧的 EF Core 版本?

标签: c# entity-framework entity-framework-core


【解决方案1】:

我有一个.HasDefaultValueSql("((0))") 在我当前的项目中工作。

还发现了 .HasDefaultValueSql("getdate()").HasDefaultValue(3); here

【讨论】:

  • 是的,我不确定发生了什么,因为所有这些都因某种原因导致空值,我似乎无法理解为什么
  • 我可以看看你的插页吗?
【解决方案2】:

我遇到了同样的问题。更新后OnModelCreating 您必须将迁移应用到数据库。写dotnet ef migrations add defaultValuesAddedToPackage,然后写dotnet ef database update。这为列类型设置了默认值,因此您无需在新实体或 sql 插入中显式设置。如果你写dotnet ef migrations script,你会看到类似ALTER TABLE [packages] ADD DEFAULT 0 FOR [State];的代码

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多