EF Core DatabaseGeneratedOption.Computed无效

时间:2018-01-08 18:06:17

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

我最近开始使用 .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批注是根据插入或更新时属性的数据类型生成数据库生成的值。

任何人都可以告诉我原因,当我尝试为我的数据库播种时它会失败。

1 个答案:

答案 0 :(得分:0)

首先,您已经在班级= DateTime.UtcNow;

中定义了Created_At的初始值。

这就是为什么它适用于 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