Reputation: 3078
I have the following model:
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;
}
And the following application context:
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"));
}
}
Next I will show you a screen of my PostgreSQL data base schema:
I'm trying to save a new entity with the help of the next code:
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);
}
But as the result I see this error. I don't understand why.
I absolutely sure that CreatedAt
field is not null during the saving. See a screen of debug:
Where is the mistake?
Upvotes: 1
Views: 2209
Reputation: 24270
Your property indeed has a value, but it is also decorated with [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
.
By using Computed
, you are telling EF Core that it must leave the property's value upto the database. In other words, the database is made fully responsible for generating or computing a value during every query. As can be read here, "The practical effect of this is that Entity Framework will not include the property in INSERT or UPDATE statements".
The generated insert statement will then look like
INSERT INTO Products (Id, Name, Description, Category, Price) ...
Which will fail because CreatedAt
has a NOT NULL setting, apparently without a default value.
You can try 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()");
}
This should work as long as it is supported for Npgsql, which I don't know for sure. If it does not work then you may have no other option but to remove the attribute and take value creation in your own hands.
Upvotes: 4