[英]C# Pomelo mySQL trigger onUpdate Timestamp
我试图在 Pomelo.MySQL 中创建一个日志表,它有一个 onUpdate 时间戳,但我似乎无法用实体框架触发它。
这是我的桌子模型
public class OrganisationLog
{
[Key]
public int Id { get; set; }
[Column(TypeName = "VARCHAR(1024)")]
[Required(AllowEmptyStrings = false)]
public string MachineName { get; set; }
[DefaultValue("CURRENT_TIMESTAMP")]
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime LastContact { get; set; }
public int OrganisationId { get; set; }
[ForeignKey("OrganisationId")]
public Organisation Organisation { get; set; }
}
下面是应该工作的功能。
private void UpdateOrganisationLog(Organisation organisation, string machineName)
{
try
{
OrganisationLog organisationLog = _context.OrganisationLogs
.Where(x => x.OrganisationId == organisation.Id && x.MachineName == machineName)
.FirstOrDefault();
if (organisationLog == null)
{
organisationLog = new OrganisationLog()
{
MachineName = machineName,
OrganisationId = organisation.Id,
LastContact = DateTime.Now
};
_context.OrganisationLogs.Add(organisationLog);
}
else
{
_context.Update(organisationLog);
}
_context.SaveChanges();
}
catch (Exception e)
{
Console.WriteLine("Error " + e.Message);
}
}
我最终使用手动 SQL 语句使其工作,但我想通过实体框架弄清楚它。
_context.Database.ExecuteSqlCommand($"UPDATE organisationlogs SET LastContact = CURRENT_TIMESTAMP(6) WHERE Id = {organisationLog.Id}");
它可能与CURRENT_TIMESTAMP(6)
而不是CURRENT_TIMESTAMP()
吗? 不知道为什么 Entity Framework 将其设为(6)
。
根据默认值上的 EF Core 文档,不支持数据注释:
您不能使用数据注释设置默认值。
如果 EF Core 支持它,那么将它用于CURRENT_TIMESTAMP
可能仍然无效,因为它不是System.DateTime
值,而是技术上的 SQL 片段。
在您的情况下,使用.HasDefaultValueSql()
指定 SQL 片段的如下 FluentAPI 配置应该适用于 Pomelo 3.0.1+:
class MyContext : DbContext
{
// ...
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<OrganisationLog>(entity =>
{
entity.Property(e => e.LastContact)
.HasDefaultValueSql("CURRENT_TIMESTAMP");
});
}
}
DatabaseGenerated(DatabaseGeneratedOption.Computed)
属性应该不是必需的。
如果您希望值不仅在创建时生成,而且在更改表行时自动更新,请改用以下模型定义:
class MyContext : DbContext
{
// ...
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<OrganisationLog>(entity =>
{
entity.Property(e => e.LastContact)
.ValueGeneratedOnAddOrUpdate();
});
}
}
如果您只想在更改表行时更新值,而不是在创建它时更新值,您可以将ValueGeneratedOnUpdate()
与 EF Core 3.1.0 一起使用。
EF Core < 3.1.0 中存在一个错误,其中ValueGeneratedOnUpdate()
不会生成正确的 C# 代码。 对于大多数人来说,这应该不是问题,因为对 EF Core 3.0.0 的终生支持无论如何都非常有限(并且如上所述,自 3.0.1 以来,该功能仅由 Pomelo 支持)。 如果您无论如何都需要 3.0.1 >= Pomelo < 3.1.0 的解决方法,那么使用ValueGeneratedOnAddOrUpdate()
将适用于大多数用例。
请参阅我们的 GitHub 存储库上的#959 ,以获取与CURRENT_TIMESTAMP
结合实现对datetime
列的支持的修复程序以及更多详细信息。
我正在使用
Pomelo.EntityFramework.MySql
版本2.1.4
。 我用 Elastic Beanstalk 托管它,所以我需要使用旧版本的 dotnet
对于 Pomelo 2.1.4
以上所有内容都无法正常工作(使用timestamp
或timestamp(6)
列可能有效,但您需要手动更改DEFAULT
语句以删除单引号,以防您为数据库搭建脚手架)。 但是您始终可以更改表定义作为解决方法。
如果您正在使用迁移,则可以将以下行(或类似内容)添加到Up()
方法中,例如:
migrationBuilder.Sql("ALTER TABLE `OrganisationLog` CHANGE COLUMN `LastContact` datetime(6) CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;");
不理想,但它应该适用于较旧的 Pomelo 版本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.