Npgsql,保存 DateTime 值时出错(列 "CreatedAt" 中的空值违反了非空约束)
Npgsql, error during saving a DateTime value (null value in column "CreatedAt" violates not-null constraint)
我有以下型号:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[ScaffoldColumn(false)]
public DateTime CreatedAt { get; set; } = DateTime.Now;
}
以及以下应用上下文:
public class ApplicationContext : DbContext
{
private readonly string _connectionString;
public DbSet<Product> Products { get; set; }
public ApplicationContext(IConfiguration configuration)
{
_connectionString = configuration.GetConnectionString("Sportshop");
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseNpgsql(_connectionString, b => b.MigrationsAssembly("Web"));
}
}
接下来我将向您展示我的 PostgreSQL 数据库模式的屏幕:
我正在尝试借助下一个代码保存新实体:
public ViewResult Index()
{
Product product = new Product
{
Name = "P1",
Category = "test",
Price = 1000,
Description = "Hello !!!"
};
_applicationContext.Products.Add(product);
_applicationContext.SaveChanges();
return View(// ... some view data);
}
但结果我看到了这个错误。我不明白为什么。
我绝对确定CreatedAt
字段在保存过程中不为空。查看调试屏幕:
哪里错了?
你的属性确实有值,但也是用[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
装饰的。
通过使用 Computed
,您告诉 EF Core 它必须将 属性 的值留给数据库。换句话说,数据库完全负责在每次查询期间生成或计算值。可以读到 here,“ 这样做的实际效果是 Entity Framework 将不会在 INSERT 或 UPDATE 语句 中包含 属性”。
生成的插入语句将类似于
INSERT INTO Products (Id, Name, Description, Category, Price) ...
这将失败,因为 CreatedAt
有一个 NOT NULL 设置,显然没有默认值。
你可以试试giving the field a default value using the Fluent API:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>()
.Property(b => b.CreatedAt)
.HasDefaultValueSql("getdate()");
}
只要 Npgsql 支持它就应该可以工作,我不确定。如果它不起作用,那么您可能别无选择,只能删除该属性并自行创造价值。
我有以下型号:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[ScaffoldColumn(false)]
public DateTime CreatedAt { get; set; } = DateTime.Now;
}
以及以下应用上下文:
public class ApplicationContext : DbContext
{
private readonly string _connectionString;
public DbSet<Product> Products { get; set; }
public ApplicationContext(IConfiguration configuration)
{
_connectionString = configuration.GetConnectionString("Sportshop");
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseNpgsql(_connectionString, b => b.MigrationsAssembly("Web"));
}
}
接下来我将向您展示我的 PostgreSQL 数据库模式的屏幕:
我正在尝试借助下一个代码保存新实体:
public ViewResult Index()
{
Product product = new Product
{
Name = "P1",
Category = "test",
Price = 1000,
Description = "Hello !!!"
};
_applicationContext.Products.Add(product);
_applicationContext.SaveChanges();
return View(// ... some view data);
}
但结果我看到了这个错误。我不明白为什么。
我绝对确定CreatedAt
字段在保存过程中不为空。查看调试屏幕:
哪里错了?
你的属性确实有值,但也是用[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
装饰的。
通过使用 Computed
,您告诉 EF Core 它必须将 属性 的值留给数据库。换句话说,数据库完全负责在每次查询期间生成或计算值。可以读到 here,“ 这样做的实际效果是 Entity Framework 将不会在 INSERT 或 UPDATE 语句 中包含 属性”。
生成的插入语句将类似于
INSERT INTO Products (Id, Name, Description, Category, Price) ...
这将失败,因为 CreatedAt
有一个 NOT NULL 设置,显然没有默认值。
你可以试试giving the field a default value using the Fluent API:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>()
.Property(b => b.CreatedAt)
.HasDefaultValueSql("getdate()");
}
只要 Npgsql 支持它就应该可以工作,我不确定。如果它不起作用,那么您可能别无选择,只能删除该属性并自行创造价值。