繁体   English   中英

如何使用 .NET Core 中的 Entity Framework Core 在日期列中插入和更新 SQL Server DateTime

[英]How to insert and update SQL Server DateTime in a date column using Entity Framework Core in .NET Core

我有一个包含LastUpdateOn列的表,每当我在表中执行插入或更新操作时,我想在此列中保留 SQL Server 当前日期和时间(使用GETDATE() )。

在 ADO.NET 中,我们曾经在插入/更新语句中调用GETDATE()函数,但是我们如何使用 Entity Framework Core 来实现相同的功能呢?

存储 SQL Server 日期时间的原因是我们不想将应用程序服务器日期时间存储在 LastUpdateOn 列中,因为应用程序将从不同的服务器上运行,并且它们的时钟可能不同步,因此我们希望存储所有地方的公共时间(应用服务器)。

我有两个快速解决方案:

  1. 简单地将值作为默认值设置为该列上的 GetDate() 并在插入或更新时将 null 传递给 EF;

  2. 创建一个在插入/更新之前调用 GetDate() 的函数并将其用作值;

编辑:

  1. 在插入/更新之前为获取 GetDate() 函数的 DateTime 值创建一个新的 EF 配置并自动执行该过程;

因此,当我远离存储过程(我经常使用“GetDate()”或“CURRENT_TIMESTAMP”)......我接受了 c#/middleware 层。

我做了一个“空检查”并将其设置在 c# 代码中(在实体框架数据层代码中)

下面显示日期时间。 DateTime.MinValue 的意思是“有人没有明确设置它”。

 myEntityFrameworkEntity.InsertDate = parameterInsertDateValue == DateTime.MinValue ? DateTime.Now : parameterInsertDateValue;

还有其他变化,但想法是一样的。 “调用者”是否明确设置了属性,或者他们没有设置它,让我代表他们写一个值。

现在,有时我不在乎调用者设置了什么。 如果它是 LastUpdatedDate ,您也可以“强制它”(始终将其设置为 DateTime.Now)......

// i don't care what the parameters are, i always update it in this layer
myEntityFrameworkEntity.LastUpdatedDate = DateTime.Now;

此外,而不是直接使用 DateTime(.Now) ......我使用这个:

https://github.com/vfabing/Chronos.Net

您“注入”了一个可以为单元测试模拟的 DateTime-PROVIDER ..。

这是一个更完整的示例来显示我的 EF 代码(对于需要“断开连接”实体的 Rest-Services)。

    public const int ExpectedAddSingleOrUpdateSingleOrDeleteSingleSaveChangesAsyncRowCount = 1;

    public async Task<EmployeeEfEntity> UpdateAsync(
        EmployeeEfEntity inputEmployee,
        CancellationToken token)
    {
        int saveChangesAsyncValue = 0;
        
        /* find the object in the db-context using the object surrogate-primary-key (since this is an update) */
        EmployeeEfEntity foundEntity =
            await this.entityDbContext.EmployeeEfEntitys.FirstOrDefaultAsync(
                item => item.EmployeeEfEntityKey == inputEmployee.EmployeeEfEntityKey,
                token);

        if (null != foundEntity)
        {
            /* update the found-entity with the properties of the input object */

            /* the "normal" properties of the employee */
            foundEntity.EmployeeBadgeNumber = inputEmployee.EmployeeBadgeNumber;

            /* if the insert-date was explicit, use it, otherwise default to date-time.now */
            foundEntity.InsertDate = inputEmployee.InsertDate == DateTime.MinValue ? DateTime.Now : inputEmployee.InsertDate;

            /* we do not care about the input parameters, we always set it to "now" */
            foundEntity.LastUpdated = inputEmployee.LastUpdated == DateTime.Now;


            this.entityDbContext.Entry(foundEntity).State = EntityState.Modified;
            saveChangesAsyncValue = await this.entityDbContext.SaveChangesAsync(token);
            if (ExpectedAddSingleOrUpdateSingleOrDeleteSingleSaveChangesAsyncRowCount != saveChangesAsyncValue)
            {
                throw new ArgumentOutOfRangeException(
                    string.Format(ErrorMsgExpectedSaveChangesAsyncRowCount, saveChangesAsyncValue),
                    (Exception)null);
            }
        }
        else
        {
            ArgumentOutOfRangeException argEx = new ArgumentOutOfRangeException(
                string.Format(ErrorMsgPrimaryEntityNotFound, inputEmployee.EmployeeEfEntityKey),
                (Exception)null);

            this.logger.LogError(argEx);
        }

        return foundEntity;
    }

我的代码实际上使用了 Chronos.Net(注入)日期时间提供程序,但我删除了它以使代码更简单地回答这个问题。

由于您使用的是实体框架,该框架旨在允许更多地在 C# 中处理数据库使用,因此我将只使用 DateTime.Now(如果您想要 UTC 时间,则使用 DateTime.UtcNow)。

每次输入/更新记录时,将LastUpdateOn设置为DateTime.NowDateTime.Utc.Now

如果你真的想使用 SQL server 的GETDATE()方法,那么编写一个存储过程,它接受一个整数(要更新的记录的 id),并使用它来将具有指定 id 的字段的LastUpdateOn设置为GETDATE() .

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM