[英].NET Core DateTime doesn't correctly insert/update DateTime column in SQL Server
[英]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 列中,因为应用程序将从不同的服务器上运行,并且它们的时钟可能不同步,因此我们希望存储所有地方的公共时间(应用服务器)。
我有两个快速解决方案:
简单地将值作为默认值设置为该列上的 GetDate() 并在插入或更新时将 null 传递给 EF;
创建一个在插入/更新之前调用 GetDate() 的函数并将其用作值;
编辑:
因此,当我远离存储过程(我经常使用“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.Now
或DateTime.Utc.Now
。
如果你真的想使用 SQL server 的GETDATE()
方法,那么编写一个存储过程,它接受一个整数(要更新的记录的 id),并使用它来将具有指定 id 的字段的LastUpdateOn
设置为GETDATE()
.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.