C# 如何自动填充CreatedDate和ModifiedDate?
我正在学习ASP.NET核心MVC,我的模型是C# 如何自动填充CreatedDate和ModifiedDate?,c#,entity-framework,asp.net-core-mvc,C#,Entity Framework,Asp.net Core Mvc,我正在学习ASP.NET核心MVC,我的模型是 namespace Joukyuu.Models { public class Passage { public int PassageId { get; set; } public string Contents { get; set; } public DateTime CreatedDate { get; set; } public DateTime Modi
namespace Joukyuu.Models
{
public class Passage
{
public int PassageId { get; set; }
public string Contents { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime ModifiedDate { get; set; }
}
}
段落
表格用于保存我写的段落
脚本
视图只有一个字段Create
用于输入文章Contents
和CreatedDate
必须由服务器自动设置为相等(使用UTC格式)ModifiedDate
视图只有一个字段Edit
用于编辑文章<代码>修改日期必须由服务器自动设置Contents
我必须将哪些属性附加到
CreatedDate
和ModifiedDate
属性,以使它们根据上述场景由服务器自动填充?如果您先使用代码,您可以尝试此方法
[Required, DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime CreatedDate { get; set; }
关于移民
AddColumn("Passage", "CreatedDate", n => n.DateTime(nullable: false, defaultValueSql: "GETDATE()"));
更多参考资料
或者您可以全局覆盖saveChanges
Note*如果您有CreatedDate
字段,这将影响整个模型
我必须将哪些属性附加到CreatedDate和ModifiedDate属性,以使服务器根据上述场景自动填充它们
解决方案1)
通过编辑,您必须自行更改/更新它
解决方案2)
自定义属性:
[SqlDefaultValue(DefaultValue = "getutcdate()")]
public DateTime CreatedDate { get; set; }
解决方案3)
借助计算机:
[Required, DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime CreatedUtc { get; set;
"dbo.Products",
c => new
{
ProductId = c.Int(nullable: false, identity: true),
Name = c.String(),
CreatedUtc = c.DateTime(nullable: false, defaultValueSql: "GETUTCDATE()"),
})
.PrimaryKey(t => t.ProductId);
解决方案4)
您还可以通过手动修改查询来使用命令拦截器完成此操作
解决方案5)
使用存储库模式管理数据创建,并通过CreateNew进行设置
这是我最喜欢的解决方案
解决方案6)
只需设置它或进入UI或虚拟机即可
在实体框架核心1.0中,轻松:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Passage>()
.Property(b => b.CreatedDate )
.HasDefaultValueSql("getdate()");
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity()
.Property(b=>b.CreatedDate)
.HasDefaultValueSql(“getdate()”);
}
对于使用异步系统(savechangessync
)和.NET Core的用户,最好覆盖DbContext
的savechangessync
方法:
public override Task<int> SaveChangesAsync(
bool acceptAllChangesOnSuccess,
CancellationToken cancellationToken = default(CancellationToken))
{
var AddedEntities = ChangeTracker.Entries()
.Where(E => E.State == EntityState.Added)
.ToList();
AddedEntities.ForEach(E =>
{
E.Property("CreationTime").CurrentValue = DateTime.Now;
});
var EditedEntities = ChangeTracker.Entries()
.Where(E => E.State == EntityState.Modified)
.ToList();
EditedEntities.ForEach(E =>
{
E.Property("ModifiedDate").CurrentValue = DateTime.Now;
});
return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}
使用savechangesync的替代方法是,您可以为相应的数据库创建数据库触发器。我为mssql、postgress、sqlite和mysql使用了一些帮助函数。下面是代码的粘贴
使用Microsoft.EntityFrameworkCore.Metadata;
使用Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
命名空间ProjectNamespace.Api.Utils
{
公共类数据库工具
{
公共类数据库密钥
{
公共字符串值生成策略;
公共对象列;
创建公共字符串DEFAULTDATE;
公共字符串DEFAULTDATE\u更新;
公共字符串日期时间;
public bool UpdateDateTrigger=true;
公共字符串提供程序名称{get;set;}
}
/*
笔记:
可以检查dataprovider是否需要updateDateTrigger并添加更新触发器
if(dbKeys.UpdateDateTrigger)
{
Sql(DatabaseTools.getUpdateDateTrigger(dbKeys.ProviderName,“TG_roles_updated_at”,“roles”,“updated_at”);
}
如果postgress不要忘记在迁移结束时删除每个不同命名更新列(更新日期、修改日期)的生成函数,例如。
受保护的覆盖无效关闭(MigrationBuilder MigrationBuilder){。。。
if(dbKeys.ProviderName==“postgress”)
{
migrationBuilder.Sql(@)
在“+@”列()处删除函数更新“+”更新的“;
");
}
postgres不支持新关键字和旧关键字的触发器中的参数。
*/
///
///非mysql实现需要在记录更新时更新datetime
///
///
///
///
///
///
///
///
公共静态字符串getUpdateDateTrigger(字符串数据库提供程序、字符串名称、字符串表、字符串列、字符串模式=”、字符串id_column=“id”)
{
字符串updateDataTrigger=null;
如果(!string.IsNullOrEmpty(架构))
schema=schema+”;
交换机(数据库提供程序)
{
案例“sqlite”:
updateDateTrigger=@”
创建触发器[“+name+@”]
之后
更新
关于“+表+@”
每行
新建时,PostgreSQL中CreationDate的“+列+@”解决方案:
builder.Property(e => e.CreationDate)
.HasColumnType("timestamp without time zone")
.HasDefaultValueSql("NOW()")
.ValueGeneratedOnAdd();
通过:
不幸的是,没有更新事件的解决方案。这太简单了。只需执行两个步骤:
1.在createDate
字段的顶部创建模型:
[Required, DatabaseGenerated(DatabaseGeneratedOption.Computed)]
2.创建迁移后,在更新此部分的数据库编辑列之前的文件中添加defaultValueSql:“getdate()”
,如下所示:
id = table.Column<int>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
CreatedDate = table.Column<DateTime>(defaultValueSql: "getdate()",nullable: false)
id=table.Column(可空:false)
.Annotation(“SqlServer:Identity”、“1,1”),
CreatedDate=table.Column(defaultValueSql:“getdate()”,可空:false)
由服务器自动设置=数据库触发器请在保存更改之前查看您可以设置日期和时间CreatedDate=DateTime。现在
我们可以在内容中插入ModifiedDate=DateTime.UtcNow();
setter吗?不,这不是一个好主意,因为实体框架稍后将使用setter来填充(materialized data=从SQL到实体的行数)。这意味着您将始终获取当前集合数据,而不是从数据库获取。关于EF Core 1的代码(最底部),为什么不使用getutcdate()builder.Property(e => e.CreationDate)
.HasColumnType("timestamp without time zone")
.HasDefaultValueSql("NOW()")
.ValueGeneratedOnAdd();
[Required, DatabaseGenerated(DatabaseGeneratedOption.Computed)]
id = table.Column<int>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
CreatedDate = table.Column<DateTime>(defaultValueSql: "getdate()",nullable: false)