我最近开始使用 .NET CORE v2 。 我正在尝试使用 web-api 模板中的代码优先方法来设置数据库。
背景:我以前使用过Laravel框架,我想在迁移文件中复制laravel的timestamp()函数,它基本上创建了两列:UpdatedAt和CreatedAt在一个表中。
当使用INSERT或UPDATE列的ORM(Elqoquent)函数时,这些列中的值将填充正确的值。它是无缝的,您无需担心它。
在我的c#代码中,我有以下模型
public class A {
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public DateTime Created_At { get; set; } = DateTime.UtcNow;
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime Updated_At { get; set; }
// I've tried to add "= DateTime.UtcNow;" at the end of Updated_At as well
}
我还有以下用于为数据库设定种子的类。
public static class DatabaseSeeder
{
private static AppContext _context;
public static void SeedDatabase(this AppContext appContext)
{
_context = appContext;
_context.Database.EnsureCreated();
// Verify if data exist.
if (_context.A.Any())
{
return;
}
SeedAs();
}
private static void SeedAs()
{
var defaults = new A[]
{
new A
{
Name = "Value 1",
},
new A
{
Name = "Value 2",
},
new A
{
Name = "Value 3",
}
};
_context.As.AddRange(defaults);
_context.SaveChanges();
}
}
在Startup类的Configure函数中调用SeedDatabase函数,如果数据库在启动时不包含任何数据,它基本上会对数据库进行播种。
问题:我遇到的问题是,当我第一次启动开发服务器时,应用程序会注意到数据库不包含任何值,因此它会尝试播种它。返回以下错误:
MySql.Data.MySqlClient.MySqlException(0x80004005):字段'Updated_At' 没有默认值
我似乎不明白为什么会失败,因为当我通过删除Updated_At属性及其注释运行相同的代码时,没有返回任何错误,数据库按预期播种Created_At字段,包含DateTime.UtcNow的值。
DatabaseGenerated的预期行为(DatabaseGeneratedOption.Computed批注是根据插入或更新时属性的数据类型生成数据库生成的值。
任何人都可以告诉我原因,当我尝试为我的数据库播种时它会失败。
答案 0 :(得分:0)
首先,您已经在班级= DateTime.UtcNow;
这就是为什么它适用于 Created_At 而不适用于 Updated_At 的原因。由于 Updated_At 没有初始值,并且数据库也没有为此列定义任何默认值。
要使其正常工作,必须在DbContext类中为SQL列定义默认值。
我想,对于MySQL,您应该使用函数 NOW():
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<A>()
.Property(s => s.Created_At )
.HasDefaultValueSql("NOW()");
modelBuilder.Entity<A>()
.Property(s => s.Updated_At )
.HasDefaultValueSql("NOW()");
}
文档:Data Annotations - DatabaseGenerated Attribute in EF 6 & EF Core