Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何自动填充CreatedDate和ModifiedDate?_C#_Entity Framework_Asp.net Core Mvc - Fatal编程技术网

C# 如何自动填充CreatedDate和ModifiedDate?

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

我正在学习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 ModifiedDate { get; set; }
    }
}
段落
表格用于保存我写的段落

脚本
  • Create
    视图只有一个字段
    Contents
    用于输入文章
    CreatedDate
    ModifiedDate
    必须由服务器自动设置为相等(使用UTC格式)

  • 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)